diff options
author | Tom de Vries <tdevries@suse.de> | 2025-01-04 10:19:37 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2025-01-04 10:19:37 +0100 |
commit | 9e2d0e2f5369bdd483973171ce436062b866d2dc (patch) | |
tree | 8f2450e8ab3f8b9f80b7a3f18f9d5887f1b69c4c | |
parent | 003ced705f6d4c10b7f0fb96acf7ec2db58f902e (diff) | |
download | gdb-9e2d0e2f5369bdd483973171ce436062b866d2dc.zip gdb-9e2d0e2f5369bdd483973171ce436062b866d2dc.tar.gz gdb-9e2d0e2f5369bdd483973171ce436062b866d2dc.tar.bz2 |
[gdb/cli] Warn about forced return from signal trampoline
The Linaro CI reported a regression on arm-linux in test-case
gdb.base/sigstep.exp following commit 7b46460a619 ("[gdb/symtab] Apply
workaround for PR gas/31115 a bit more") [1]:
...
(gdb) return^M
Make __default_sa_restorer return now? (y or n) n^M
Not confirmed^M
(gdb) FAIL: $exp: return from handleri: \
leave signal trampoline (got interactive prompt)
...
After installing package glibc-debuginfo and adding --with-separate-debug-dir
to the configure flags, I managed to reproduce the FAIL.
The regression seems to be a progression in the sense that the function name
for the signal trampoline is found.
After reading up on the signal trampoline [2] and the return command [3], my
understanding is that forced returning from the signal trampoline is
potentially unsafe, given that for instance the process signal mask won't be
restored.
Fix this by:
- rather than using the name, using "signal trampoline" in the query, and
- adding a warning about returning from a signal trampoline,
giving us:
...
(gdb) return^M
warning: Returning from signal trampoline does not fully restore pre-signal \
state, such as process signal mask.^M
Make signal trampoline return now? (y or n) y^M
87 dummy = 0; dummy = 0; while (!done);^M
(gdb) PASS: $exp: return from handleri: leave signal trampoline (in main)
...
Tested on x86_64-linux.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
[1] https://linaro.atlassian.net/browse/GNU-1459
[2] https://man7.org/linux/man-pages/man2/sigreturn.2.html
[3] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Returning.html
-rw-r--r-- | gdb/stack.c | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/sigstep.exp | 2 |
2 files changed, 9 insertions, 2 deletions
diff --git a/gdb/stack.c b/gdb/stack.c index 4a3e7e4..9785a94 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -2776,7 +2776,14 @@ return_command (const char *retval_exp, int from_tty) { int confirmed; - if (thisfun == NULL) + if (get_frame_type (thisframe) == SIGTRAMP_FRAME) + { + warning (_("Returning from signal trampoline does not fully restore" + " pre-signal state, such as process signal mask.")); + confirmed = query (_("%sMake signal trampoline return now? "), + query_prefix.c_str ()); + } + else if (thisfun == NULL) confirmed = query (_("%sMake selected stack frame return now? "), query_prefix.c_str ()); else diff --git a/gdb/testsuite/gdb.base/sigstep.exp b/gdb/testsuite/gdb.base/sigstep.exp index 315d89d..d08a34e 100644 --- a/gdb/testsuite/gdb.base/sigstep.exp +++ b/gdb/testsuite/gdb.base/sigstep.exp @@ -259,7 +259,7 @@ proc advancei { cmd } { -re "return .*${gdb_prompt} $" { fail "$test (stepped)" } - -re "Make .*frame return now.*y or n. $" { + -re "Make signal trampoline return now.*y or n. $" { send_gdb "y\n" exp_continue -continue_timer } |