This is the mail archive of the
gdb-prs@sourceware.org
mailing list for the GDB project.
[Bug gdb/17511] New: Program received signal SIGTRAP, after step to signal handler -> step inside handler -> continue
- From: "palves at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: gdb-prs at sourceware dot org
- Date: Sun, 26 Oct 2014 22:15:10 +0000
- Subject: [Bug gdb/17511] New: Program received signal SIGTRAP, after step to signal handler -> step inside handler -> continue
- Auto-submitted: auto-generated
https://sourceware.org/bugzilla/show_bug.cgi?id=17511
Bug ID: 17511
Summary: Program received signal SIGTRAP, after step to signal
handler -> step inside handler -> continue
Product: gdb
Version: HEAD
Status: NEW
Severity: normal
Priority: P2
Component: gdb
Assignee: unassigned at sourceware dot org
Reporter: palves at redhat dot com
While writing a GDB test I noticed that when I have a signal pending/queued,
and I single-step into signal handler, and then issue another step inside the
handler, the following continues will result in spurious SIGTRAPS.
The problem is that $eflags.TF ends stuck/set.
I'm on Fedora 20 (Linux 3.16.4-200.fc20.x86_64).
Vis:
(gdb) start
Temporary breakpoint 1, main () at si-handler.c:48
48 setup ();
(gdb) next
50 global = 0; /* set break here */
Let's queue a signal, so we can step into the handler:
(gdb) handle SIGUSR1
Signal Stop Print Pass to program Description
SIGUSR1 Yes Yes Yes User defined signal 1
(gdb) info inferiors
Num Description Executable
* 1 process 29953 si-handler
(gdb) shell kill -SIGUSR1 29953
(gdb) c
Continuing.
Program received signal SIGUSR1, User defined signal 1.
main () at si-handler.c:50
50 global = 0; /* set break here */
(gdb) display $eflags
1: $eflags = [ PF ZF IF ]
(With mainline GDB, you can instead just do "queue-signal SIGUSR1".)
Now step into the handler -- "si" does PTRACE_SINGLESTEP+SIGUSR1:
(gdb) si
sigusr1_handler (sig=0) at si-handler.c:31
31 {
1: $eflags = [ PF ZF IF ]
Looks fine so far. But another single-step...
(gdb) si
0x0000000000400621 31 {
1: $eflags = [ PF ZF TF IF ]
... ends up with TF left set. This results in PTRACE_CONTINUE trapping
after each instruction is executed:
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000000400624 in sigusr1_handler (sig=0) at si-handler.c:31
31 {
1: $eflags = [ PF ZF TF IF ]
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
sigusr1_handler (sig=10) at si-handler.c:32
32 global = 0;
1: $eflags = [ PF ZF TF IF ]
(gdb)
Note that even another PTRACE_SINGLESTEP does not fix it:
(gdb) si
33 }
1: $eflags = [ PF ZF TF IF ]
(gdb)
Eventually, it gets "fixed" by the rt_sigreturn syscall, when returning
out of the handler:
(gdb) bt
#0 sigusr1_handler (sig=10) at si-handler.c:33
#1 <signal handler called>
#2 main () at si-handler.c:50
(gdb) set disassemble-next-line on
(gdb) si
0x0000000000400632 33 }
0x0000000000400631 <sigusr1_handler+17>: 5d pop %rbp
=> 0x0000000000400632 <sigusr1_handler+18>: c3 retq
1: $eflags = [ PF ZF TF IF ]
(gdb)
<signal handler called>
=> 0x0000003b36a358f0 <__restore_rt+0>: 48 c7 c0 0f 00 00 00 mov
$0xf,%rax
1: $eflags = [ PF ZF TF IF ]
(gdb) si
<signal handler called>
=> 0x0000003b36a358f7 <__restore_rt+7>: 0f 05 syscall
1: $eflags = [ PF ZF TF IF ]
(gdb)
main () at si-handler.c:50
50 global = 0; /* set break here */
=> 0x000000000040066b <main+9>: c7 05 cb 09 20 00 00 00 00 00 movl
$0x0,0x2009cb(%rip) # 0x601040 <global>
1: $eflags = [ PF ZF IF ]
(gdb)
I don't get the bug if I instead PTRACE_CONTINUE into the signal
handler -- e.g., set a breakpoint in the handler, queue a signal,
and "continue".
Below's the code I was using to test this.
~~~~
/* 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 <signal.h>
volatile int global;
static void
signal_handler (int sig)
{
global = 0;
global = 0;
global = 0;
global = 0;
global = 0;
}
void
setup (void)
{
/* Set up the signal handler. */
signal (SIGUSR1, signal_handler);
}
void
begin (void)
{
}
void
end (void)
{
}
int
main (void)
{
setup ();
begin ();
end ();
return 0;
}
~~~~
--
You are receiving this mail because:
You are on the CC list for the bug.