Skip to content

Commit

Permalink
PR gdb/17300: Input after "c -a" crashes readline/GDB
Browse files Browse the repository at this point in the history
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
 adapteva#1  0x0000003b36a36f68 in __GI_abort () at abort.c:89
 adapteva#2  0x0000000000784aa9 in rl_callback_read_char () at readline/callback.c:116
 adapteva#3  0x0000000000619181 in rl_callback_read_char_wrapper (client_data=0x0) at gdb/event-top.c:167
 adapteva#4  0x0000000000619557 in stdin_event_handler (error=0, client_data=0x0) at gdb/event-top.c:373
 adapteva#5  0x000000000061814a in handle_file_event (data=...) at gdb/event-loop.c:763
 adapteva#6  0x0000000000617631 in process_event () at gdb/event-loop.c:340
 adapteva#7  0x00000000006176f8 in gdb_do_one_event () at gdb/event-loop.c:404
 adapteva#8  0x0000000000617748 in start_event_loop () at gdb/event-loop.c:429
 adapteva#9  0x00000000006191b3 in cli_command_loop (data=0x0) at gdb/event-top.c:182
 adapteva#10 0x000000000060f538 in current_interp_command_loop () at gdb/interps.c:318
 adapteva#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  <[email protected]>

	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  <[email protected]>

	PR gdb/17300
	* gdb.base/continue-all-already-running.c: New file.
	* gdb.base/continue-all-already-running.exp: New file.
  • Loading branch information
palves committed Oct 17, 2014
1 parent 04f0515 commit e37951d
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 0 deletions.
7 changes: 7 additions & 0 deletions gdb/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
2014-10-17 Pedro Alves <[email protected]>

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 <[email protected]>

PR gdb/17472
Expand Down
18 changes: 18 additions & 0 deletions gdb/infcmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,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);
}
Expand Down
6 changes: 6 additions & 0 deletions gdb/testsuite/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2014-10-17 Pedro Alves <[email protected]>

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 <[email protected]>

PR gdb/17472
Expand Down
25 changes: 25 additions & 0 deletions gdb/testsuite/gdb.base/continue-all-already-running.c
Original file line number Diff line number Diff line change
@@ -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 changes: 79 additions & 0 deletions gdb/testsuite/gdb.base/continue-all-already-running.exp
Original file line number Diff line number Diff line change
@@ -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
}
}

0 comments on commit e37951d

Please sign in to comment.