mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-29 04:53:56 +08:00
PR gdb/17300: Input after "c -a" crashes readline/GDB
If all threads in the target were already running when the user does "c -a", nothing puts the inferior's terminal settings in effect and removes stdin from the event loop, which we must when running a foreground command. The result is that user input afterwards crashes readline/gdb: (gdb) start Temporary breakpoint 1 at 0x4005d4: file continue-all-already-running.c, line 23. Starting program: continue-all-already-running Temporary breakpoint 1, main () at continue-all-already-running.c:23 23 sleep (10); (gdb) c -a& Continuing. (gdb) c -a Continuing. p 1 readline: readline_callback_read_char() called with no handler! Aborted (core dumped) $ Backtrace: Program received signal SIGABRT, Aborted. 0x0000003b36a35877 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); (top-gdb) p 1 $1 = 1 (top-gdb) bt #0 0x0000003b36a35877 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x0000003b36a36f68 in __GI_abort () at abort.c:89 #2 0x0000000000784aa9 in rl_callback_read_char () at readline/callback.c:116 #3 0x0000000000619181 in rl_callback_read_char_wrapper (client_data=0x0) at gdb/event-top.c:167 #4 0x0000000000619557 in stdin_event_handler (error=0, client_data=0x0) at gdb/event-top.c:373 #5 0x000000000061814a in handle_file_event (data=...) at gdb/event-loop.c:763 #6 0x0000000000617631 in process_event () at gdb/event-loop.c:340 #7 0x00000000006176f8 in gdb_do_one_event () at gdb/event-loop.c:404 #8 0x0000000000617748 in start_event_loop () at gdb/event-loop.c:429 #9 0x00000000006191b3 in cli_command_loop (data=0x0) at gdb/event-top.c:182 #10 0x000000000060f538 in current_interp_command_loop () at gdb/interps.c:318 #11 0x0000000000610701 in captured_command_loop (data=0x0) at gdb/main.c:323 #12 0x000000000060c3f5 in catch_errors (func=0x6106e6 <captured_command_loop>, func_args=0x0, errstring=0x9002c1 "", mask=RETURN_MASK_ALL) at gdb/exceptions.c:237 #13 0x0000000000611bff in captured_main (data=0x7fffffffd780) at gdb/main.c:1151 #14 0x000000000060c3f5 in catch_errors (func=0x610afe <captured_main>, func_args=0x7fffffffd780, errstring=0x9002c1 "", mask=RETURN_MASK_ALL) at gdb/exceptions.c:237 #15 0x0000000000611c28 in gdb_main (args=0x7fffffffd780) at gdb/main.c:1159 #16 0x000000000045ef97 in main (argc=5, argv=0x7fffffffd888) at gdb/gdb.c:32 (top-gdb) Tested on x86_64 Fedora 20, native and gdbserver. gdb/ 2014-10-17 Pedro Alves <palves@redhat.com> PR gdb/17300 * infcmd.c (continue_1): If continuing all threads in the foreground, make sure the inferior's terminal settings are put in effect. gdb/testsuite/ 2014-10-17 Pedro Alves <palves@redhat.com> PR gdb/17300 * gdb.base/continue-all-already-running.c: New file. * gdb.base/continue-all-already-running.exp: New file.
This commit is contained in:
parent
6fdebc3d1c
commit
0ff33695ee
@ -1,3 +1,10 @@
|
||||
2014-10-17 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/17300
|
||||
* infcmd.c (continue_1): If continuing all threads in the
|
||||
foreground, make sure the inferior's terminal settings are put in
|
||||
effect.
|
||||
|
||||
2014-10-17 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/17472
|
||||
|
18
gdb/infcmd.c
18
gdb/infcmd.c
@ -735,6 +735,24 @@ continue_1 (int all_threads)
|
||||
|
||||
iterate_over_threads (proceed_thread_callback, NULL);
|
||||
|
||||
if (sync_execution)
|
||||
{
|
||||
/* If all threads in the target were already running,
|
||||
proceed_thread_callback ends up never calling proceed,
|
||||
and so nothing calls this to put the inferior's terminal
|
||||
settings in effect and remove stdin from the event loop,
|
||||
which we must when running a foreground command. E.g.:
|
||||
|
||||
(gdb) c -a&
|
||||
Continuing.
|
||||
<all threads are running now>
|
||||
(gdb) c -a
|
||||
Continuing.
|
||||
<no thread was resumed, but the inferior now owns the terminal>
|
||||
*/
|
||||
target_terminal_inferior ();
|
||||
}
|
||||
|
||||
/* Restore selected ptid. */
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
2014-10-17 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/17300
|
||||
* gdb.base/continue-all-already-running.c: New file.
|
||||
* gdb.base/continue-all-already-running.exp: New file.
|
||||
|
||||
2014-10-17 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/17472
|
||||
|
25
gdb/testsuite/gdb.base/continue-all-already-running.c
Normal file
25
gdb/testsuite/gdb.base/continue-all-already-running.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
sleep (10);
|
||||
return 0; /* set break here */
|
||||
}
|
79
gdb/testsuite/gdb.base/continue-all-already-running.exp
Normal file
79
gdb/testsuite/gdb.base/continue-all-already-running.exp
Normal file
@ -0,0 +1,79 @@
|
||||
# Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Test that "c -a" doesn't leave GDB processing input, even if all
|
||||
# threads were already running. PR gdb/17300.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_test_no_output "set non-stop on"
|
||||
|
||||
if ![runto_main] {
|
||||
return
|
||||
}
|
||||
|
||||
set linenum [gdb_get_line_number "set break here"]
|
||||
gdb_breakpoint "$linenum"
|
||||
|
||||
gdb_test "c -a&" "Continuing\\."
|
||||
|
||||
set test "no stop"
|
||||
gdb_test_multiple "" $test {
|
||||
-timeout 1
|
||||
timeout {
|
||||
pass $test
|
||||
}
|
||||
}
|
||||
|
||||
# Paranoia. Check that input works after bg command.
|
||||
gdb_test "print 1" " = 1"
|
||||
|
||||
# Continue in the foreground, and wait one second to make sure the
|
||||
# inferior really starts running. If we get a prompt to soon (e.g.,
|
||||
# the program stops), this issues a fail.
|
||||
set saw_continuing 0
|
||||
set test "c -a"
|
||||
gdb_test_multiple "c -a" $test {
|
||||
-timeout 1
|
||||
-re "Continuing\\." {
|
||||
set saw_continuing 1
|
||||
exp_continue
|
||||
}
|
||||
timeout {
|
||||
gdb_assert $saw_continuing $test
|
||||
}
|
||||
}
|
||||
|
||||
# Type something while the inferior is running in the foreground.
|
||||
send_gdb "print 2\n"
|
||||
|
||||
# Poor buggy GDB would crash before the breakpoint was hit.
|
||||
set test "breakpoint hit"
|
||||
gdb_test_multiple "" $test {
|
||||
-re "set break here ..\r\n$gdb_prompt " {
|
||||
pass $test
|
||||
}
|
||||
}
|
||||
|
||||
set test "print command result"
|
||||
gdb_test_multiple "" $test {
|
||||
-re " = 2\r\n$gdb_prompt $" {
|
||||
pass $test
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user