aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
diff options
context:
space:
mode:
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2020-10-30 08:13:57 +0100
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2020-10-30 08:15:20 +0100
commitb78b3a297b981e2c8492823e2c54436e2451c2fa (patch)
tree59d3172eef410e43451791ab649671b968ed4ea6 /gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
parentd70bdd3cc4cfdfd30bed44a271ff80f98b96eebf (diff)
downloadfsf-binutils-gdb-b78b3a297b981e2c8492823e2c54436e2451c2fa.zip
fsf-binutils-gdb-b78b3a297b981e2c8492823e2c54436e2451c2fa.tar.gz
fsf-binutils-gdb-b78b3a297b981e2c8492823e2c54436e2451c2fa.tar.bz2
gdb/infrun: disable pagination in fetch_inferior_event
Having pagination enabled when handling an inferior event gives the user an option to quit, which causes early exit in GDB's flow and may lead to half-baked state. For instance, here is a case where we quit in the middle of handling an inferior exit: $ gdb ./a.out Reading symbols from ./a.out... (gdb) set height 2 (gdb) run Starting program: ./a.out --Type <RET> for more, q to quit, c to continue without paging--q Quit Couldn't get registers: No such process. (gdb) set height unlimited Couldn't get registers: No such process. (gdb) info threads Id Target Id Frame * 1 process 27098 Couldn't get registers: No such process. Couldn't get registers: No such process. (gdb) Or suppose having a multi-threaded program like below: static void * fun (void *dummy) { int a = 1; /* break-here */ return NULL; } int main (void) { pthread_t thread; pthread_create (&thread, NULL, fun, NULL); pthread_join (thread, NULL); return 0; } If we define a breakpoint at line "break-here", we expect only Thread 2 to hit it. $ gdb ./a.out Reading symbols from ./a.out... (gdb) break 7 Breakpoint 1 at 0x1182: file mt.c, line 7. (gdb) set height 2 (gdb) run Starting program: ./a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff77c4700 (LWP 23048)] --Type <RET> for more, q to quit, c to continue without paging--q Quit (gdb) set height unlimited (gdb) info thread Id Target Id Frame * 1 Thread 0x7ffff7fe3740 (LWP 23044) "a.out" 0x00007ffff7bbed2d in ... 2 Thread 0x7ffff77c4700 (LWP 23048) "a.out" fun (dummy=0x0) at mt.c:7 (gdb) The prompt for continuation was triggered because Thread 2 hit the breakpoint. (If we had hit 'c', we were going to see that stop event, but we didn't.) The context did not switch to Thread 2. GDB also did not execute several other things it would normally do in infrun.c:normal_stop after outputting "[Switching to Thread ...]" (but it seems harmless in this case). If we 'continue' at this state, both threads run until termination, and we don't see the breakpoint hit event ever. Here is another related and more complicated scenario that leads to a GDB crash. Create two inferiors, one sitting on top of a native target, and the other on a remote target, so that we have a multi-target setting, like so: (gdb) i inferiors Num Description Connection Executable 1 process 13786 1 (native) a.out * 2 process 13806 2 (remote ...) target:a.out Next, resume both inferiors to run until termination: (gdb) set schedule-multiple on (gdb) set height 2 (gdb) continue Continuing. --Type <RET> for more, q to quit, c to continue without paging--[Inferior 2 (process 13806) exited normally] terminate called after throwing an instance of 'gdb_exception_error' Aborted Here, GDB first received a termination event from Inferior 1. GDB attempted to print this event, triggering a "prompt for continue", and GDB started polling for events, hoping to get an input from the user. However, the exit event from Inferior 2 was received instead. So, GDB started processing an exit event while being in the middle of processing another exit event. It was not ready for this situation and eventually crashed. To address these cases, temporarily disable pagination in fetch_inferior_event. This doesn't affect commands like 'info threads', 'backtrace', or 'thread apply'. Regression-tested on X86_64 Linux. gdb/ChangeLog: 2020-10-30 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (fetch_inferior_event): Temporarily disable pagination. gdb/testsuite/ChangeLog: 2020-10-30 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.base/paginate-after-ctrl-c-running.exp: Update with no pagination behavior. * gdb.base/paginate-bg-execution.exp: Ditto. * gdb.base/paginate-inferior-exit.exp: Ditto. * gdb.base/double-prompt-target-event-error.c: Remove. * gdb.base/double-prompt-target-event-error.exp: Remove.
Diffstat (limited to 'gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp')
-rw-r--r--gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp25
1 files changed, 9 insertions, 16 deletions
diff --git a/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp b/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
index 09f6fbf..f904912 100644
--- a/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
+++ b/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
@@ -24,12 +24,12 @@ if {[build_executable "failed to prepare" $testfile $srcfile debug] == -1} {
return -1
}
-# Send a ctrl-c while the target is running and the next output causes
-# a pagination prompt.
+# Send a ctrl-c while the target is running and check that the output
+# does not cause a pagination prompt.
-proc test_ctrlc_while_target_running_paginates {} {
+proc test_ctrlc_while_target_running_does_not_paginate {} {
global binfile srcfile
- global gdb_prompt pagination_prompt
+ global gdb_prompt
set testline [gdb_get_line_number "after sleep"]
@@ -62,18 +62,11 @@ proc test_ctrlc_while_target_running_paginates {} {
send_gdb "\003"
# GDB now intercepts the SIGINT and tries to let the user know
- # about the spurious signal, but that paginates. Make sure
- # the user can respond to the pagination query.
- set test "got prompt"
- set saw_pagination_prompt 0
- gdb_test_multiple "" $test {
- -re "$pagination_prompt$" {
- set saw_pagination_prompt 1
- send_gdb "\n"
- exp_continue
- }
+ # about the spurious signal. Make sure that this does not
+ # trigger pagination.
+ gdb_test_multiple "" "no pagination" {
-re "$gdb_prompt $" {
- gdb_assert $saw_pagination_prompt $test
+ pass $gdb_test_name
}
}
@@ -85,4 +78,4 @@ proc test_ctrlc_while_target_running_paginates {} {
}
}
-test_ctrlc_while_target_running_paginates
+test_ctrlc_while_target_running_does_not_paginate