aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/py-block.c
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2024-09-23 09:53:54 +0200
committerTom de Vries <tdevries@suse.de>2024-09-23 09:53:54 +0200
commitdca18cb6a100fa87d6478a465e48ddc1d9ed943a (patch)
tree5081c914c2700efdb4e917668e95dc13feacdacc /gdb/python/py-block.c
parentbee9d0068824629a136afc02818a1495209186ae (diff)
downloadbinutils-dca18cb6a100fa87d6478a465e48ddc1d9ed943a.zip
binutils-dca18cb6a100fa87d6478a465e48ddc1d9ed943a.tar.gz
binutils-dca18cb6a100fa87d6478a465e48ddc1d9ed943a.tar.bz2
[gdb/testsuite] Fix failure in gdb.threads/signal-sigtrap.exp
The test-case gdb.threads/signal-sigtrap.exp: - installs a signal handler called sigtrap_handler for SIGTRAP, - sets a breakpoint on sigtrap_handler, and - expects the breakpoint to trigger after issuing "signal SIGTRAP". Usually, that happens indeed: ... (gdb) signal SIGTRAP^M Continuing with signal SIGTRAP.^M ^M Thread 1 "signal-sigtrap" hit Breakpoint 2, sigtrap_handler (sig=5)^M 28 }^M (gdb) PASS: $exp: sigtrap thread 1: signal SIGTRAP reaches handler ... Occasionally, I run into this failure on openSUSE Tumbleweed: ... (gdb) signal SIGTRAP^M Continuing with signal SIGTRAP.^M ^M Thread 1 "signal-sigtrap" received signal SIGTRAP, Trace/breakpoint trap.^M __pthread_create_2_1 () at pthread_create.c:843^M (gdb) FAIL: $exp: sigtrap thread 1: signal SIGTRAP reaches handler ... AFAIU, the problem is in the situation that is setup before issuing that command, by running to a breakpoint in thread_function: ... void *thread_function (void *arg) { return NULL; } int main (void) { pthread_t child_thread; signal (SIGTRAP, sigtrap_handler); pthread_create (&child_thread, NULL, thread_function, NULL); pthread_join (child_thread, NULL); return 0; } ... In the passing case, thread 2 is stopped in thread_function, and thread 1 is stopped somewhere in pthread_join: ... (gdb) info threads^M Id Target Id Frame ^M 1 Thread ... (LWP ...) "signal-sigtrap" __futex_abstimed_wait_common64 () * 2 Thread ... (LWP ...) "signal-sigtrap" thread_function () ... In the failing case, thread 2 is stopped in thread_function, but thread 1 is stopped somewhere in pthread_create: ... (gdb) info threads^M Id Target Id Frame ^M 1 Thread ... (LWP ...) "signal-sigtrap" __GI___clone3 () * 2 Thread ... (LWP ...) "signal-sigtrap" thread_function () ... What I think happens is that pthread_create blocks SIGTRAP at some point, and if the "signal SIGTRAP" command is issued while that is the case, the signal becomes pending and consequently there's no longer a guarantee that the signal will be delivered to the inferior. Instead the signal will be handled by gdb like this: ... (gdb) info signals SIGTRAP Signal Stop Print Pass to program Description SIGTRAP Yes Yes No Trace/breakpoint trap ... Fix this by adding a barrier that ensures that pthread_create is done before we issue the "signal SIGTRAP" command. Likewise in test-case gdb.threads/signal-command-handle-nopass.exp. Using the fixed test-case, I tested my theory by explicitly blocking SIGTRAP: ... + sigset_t old_ss, new_ss; + sigemptyset (&new_ss); + sigaddset (&new_ss, SIGTRAP); + sigprocmask (SIG_BLOCK, &new_ss, &old_ss); + /* Make sure that pthread_create is done once the breakpoint on thread_function triggers. */ pthread_barrier_wait (&barrier); pthread_join (child_thread, NULL); + sigprocmask (SIG_SETMASK, &old_ss, NULL); ... and managed to reproduce the same failure: ... (gdb) signal SIGTRAP^M Continuing with signal SIGTRAP.^M [Thread 0x7ffff7c00700 (LWP 13254) exited]^M ^M Thread 1 "signal-sigtrap" received signal SIGTRAP, Trace/breakpoint trap.^M 0x00007ffff7c80056 in __GI___sigprocmask () sigprocmask.c:39^M (gdb) FAIL: $exp: sigtrap thread 1: signal SIGTRAP reaches handler ... Tested on x86_64-linux. PR testsuite/26867 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26867
Diffstat (limited to 'gdb/python/py-block.c')
0 files changed, 0 insertions, 0 deletions