Failure to software single-step into signal handler

Bug #615978 reported by Ulrich Weigand
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GDB
Fix Released
Medium
Ulrich Weigand

Bug Description

GDB is unable to correctly find the location of fixed argument in routines having variable argument lists. This seems to be related to an issue with correctly accounting for the vararg save area in the stack frame when computing stack offsets. At this point, I'm not sure whether this is a GCC or GDB bug.

GDB testsuite failures related to this bug include:
FAIL: gdb.base/annota1.exp: send SIGUSR1 (timeout)
FAIL: gdb.base/annota1.exp: backtrace @ signal handler (timeout)
FAIL: gdb.base/annota3.exp: send SIGUSR1 (pattern 4)
FAIL: gdb.base/annota3.exp: backtrace @ signal handler (pattern 1)

Tags: testsuite

Related branches

Changed in gdb-linaro:
importance: Undecided → Medium
Revision history for this message
Yao Qi (yao-codesourcery) wrote :

Here are the minimal steps to reproduce two failures in annota3.exp,

1. Fire gdb, and set breakpoints on main, handle_USR1 and printf,
$ ./gdb testsuite/gdb.base/annota3
(gdb) b main
(gdb) b handle_USR1
(gdb) b printf

2. Run and continue to breakpoint on printf. Now signal handler (handle_USR1) has been installed.
(gdb) run
Starting program: /home/yao/maverick/home/yao/git/build/gdb/testsuite/gdb.base/annota3
Breakpoint 1, main () at ../../../gdb/gdb/testsuite/gdb.base/annota3.c:32
32 int my_array[3] = { 1, 2, 3 };
(gdb) c
Continuing.
Breakpoint 3, 0x400d4516 in printf () from /lib/libc.so.6

3. Sent signal SIGUSR1 to child, and the expected behavior of GDB stops at function handle_USR1. Unfortunately, GDB stops at printf.
(gdb) signal SIGUSR1
Breakpoint 3, 0x400d4516 in printf () from /lib/libc.so.6

Some debug message is shown below,

infrun: clear_proceed_status_thread (process 16469)
infrun: proceed (addr=0xffffffff, signal=30, step=0)
infrun: resume (step=1, signal=30), trap_expected=1 // <-- [1]
infrun: wait_for_inferior (treat_exec_as_sigtrap=0)
infrun: target_wait (-1, status) =
infrun: 16469 [process 16469],
infrun: status->kind = stopped, signal = SIGTRAP
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400d4518
infrun: software single step trap for process 16469
infrun: no stepping, continue
infrun: resume (step=0, signal=0), trap_expected=0
value is 7
infrun: prepare_to_wait
infrun: target_wait (-1, status) =
infrun: 16469 [process 16469],
infrun: status->kind = stopped, signal = SIGTRAP
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400d4516
infrun: BPSTAT_WHAT_STOP_NOISY
infrun: stop_stepping

GDB does a software single step on [1] with signal 30, but seems kernel doesn't deliver this signal to child, so that breakpoint on signal handler is not hit. This is same as LP:649121.

Revision history for this message
Ulrich Weigand (uweigand) wrote :

Confirmed. It seems my original analysis was in error, sorry.
I'll change the summary line.

summary: - Debug info for arguments of varargs routines
+ Failure to deliver signal while at breakpoint location
Changed in gdb-linaro:
status: New → Confirmed
Revision history for this message
Ulrich Weigand (uweigand) wrote : Re: Failure to deliver signal while at breakpoint location

A duplicate of this problem is LP:649121, which is about those failures:

FAIL: gdb.base/sigstep.exp: step on breakpoint, to handler; performing step
FAIL: gdb.base/sigstep.exp: next on breakpoint, to handler; performing next
FAIL: gdb.base/sigstep.exp: continue on breakpoint, to handler; performing continue
FAIL: gdb.base/sigstep.exp: step on breakpoint, to handler entry; performing step
FAIL: gdb.base/sigstep.exp: next on breakpoint, to handler entry; performing next
FAIL: gdb.base/sigstep.exp: continue on breakpoint, to handler entry; performing continue

tags: added: testsuite
Changed in gdb-linaro:
assignee: nobody → Ulrich Weigand (uweigand)
status: Confirmed → In Progress
Revision history for this message
Ulrich Weigand (uweigand) wrote :

It turns out there is no kernel problem involved, this is purely a GDB bug.

When a signal is about to be delivered while we're at a breakpoint location, GDB attempts to single-step over that breakpoint (with breakpoints removed) while delivering the signal. Since ARM doesn't support hardware single-stepping, GDB uses software single step breakpoints. However, this requires GDB to know the set of potential next instruction addresses. In the case of signal delivery, this would include the address of the signal handler -- which GDB doesn't know.

Therefore, "single-stepping" actually completely executes the signal handler -- with all breakpoints removed, so breakpoints intended to be installed in the handler code will never trigger. This causes the (incorrect) appearance that the signal isn't delivered ...

I'll (once again) update the summary line to more precisely indicate the problem.

One option of fixing the problem might be to never single-step into signal delivery (at least not if we do software single stepping). Instead, GDB could postpone stepping off the breakpoint at the current location until after the signal handler has completed.

I'll work on a fix along those lines.

summary: - Failure to deliver signal while at breakpoint location
+ Failure to software single-step into signal handler
Revision history for this message
Ulrich Weigand (uweigand) wrote :
Revision history for this message
Ulrich Weigand (uweigand) wrote :
Revision history for this message
Ulrich Weigand (uweigand) wrote :
Changed in gdb-linaro:
status: In Progress → Fix Committed
Revision history for this message
Ulrich Weigand (uweigand) wrote :

All fixes backported to Linaro GDB 7.2.

Changed in gdb-linaro:
milestone: none → 7.2-2011.05-0
Michael Hope (michaelh1)
Changed in gdb-linaro:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.