diff options
author | Tom de Vries <tdevries@suse.de> | 2024-10-22 08:53:51 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-10-22 08:53:51 +0200 |
commit | 9858f29e6a9ebc02a70e6e31d54404f13fbf4b10 (patch) | |
tree | 4ae8c7585c795d3030456f6d29a718a60a445ab5 /gdb | |
parent | 3790b9f7ff23857e44b58d4b710b1f014d956ef3 (diff) | |
download | gdb-9858f29e6a9ebc02a70e6e31d54404f13fbf4b10.zip gdb-9858f29e6a9ebc02a70e6e31d54404f13fbf4b10.tar.gz gdb-9858f29e6a9ebc02a70e6e31d54404f13fbf4b10.tar.bz2 |
[gdb] Handle EINTR in run_under_shell
When building gdb with -O2 -fsanitize=thread and running test-case
gdb.base/bg-exec-sigint-bp-cond.exp, I run into:
...
(gdb) c&^M
Continuing.^M
(gdb) Quit^M
(gdb) quit_count=1
^M
Breakpoint 2, foo () at bg-exec-sigint-bp-cond.c:23^M
23 return 0;^M
FAIL: $exp: no force memory write: \
SIGINT does not interrupt background execution
...
What happens is that:
- the breakpoint hits
- while evaluating the condition of the breakpoint,
$_shell("kill -INT <pid-of-gdb>") is called, handled by run_under_shell
- in run_under_shell, a vfork is issued
- in the vfork child, execl executes the kill command
- in the vfork parent, waitpid is called to wait for the result of the kill
command
- waitpid returns -1 with errno set to EINTR
- run_under_shell doesn't check the result of waitpid, and returns the
value of local variable status. Since waitpid returned -1, status was
not assigned a value, so it's uninitialized, and happens to be
non-zero
- the breakpoint condition evaluates to true, because
$_shell("kill -INT <pid-of-gdb>") != 0
- the breakpoint triggers a stop, which the test-case doesn't expect.
Fix this by using gdb::handle_eintr to call waitpid in run_under_shell.
Also handle the case that waitpid returns an error other than EINTR, using
perror_with_name.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR gdb/30695
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30695
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/cli/cli-cmds.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index ea2e156..65ac7d6 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -55,6 +55,7 @@ #include "extension.h" #include "gdbsupport/pathstuff.h" #include "gdbsupport/gdb_tilde_expand.h" +#include "gdbsupport/eintr.h" #ifdef TUI #include "tui/tui.h" @@ -921,7 +922,11 @@ run_under_shell (const char *arg, int from_tty) } if (pid != -1) - waitpid (pid, &status, 0); + { + int ret = gdb::handle_eintr (-1, ::waitpid, pid, &status, 0); + if (ret == -1) + perror_with_name ("Cannot get status of shell command"); + } else error (_("Fork failed")); return status; |