[patch/rfc] Use frame_type for sigtramp test in infrun.c

Andrew Cagney
2004-03-16T18:57:01Z

[-- Attachment #1: Type: text/plain, Size: 990 bytes --]

Hello,

The attached patch modifies infrun.c so that, for the non-legacy case,
the test:
frame_type == SIGTRAMP frame
&& step_frame_id != stop_frame_id
is used to determine if a single-step caused the inferior to stumble
into a signal trampoline (either via a signal, or by returning from the
handler). This replaces two pc_in_sigtramp calls and a stack-pointer
heuristic -- not the most robust of tests.

The new test:

- eliminates the call pc_in_sigtramp(step_pc)
(i.e., on the PC from before the single step) (this was an unexpected
bonus :-)

- uses the caching call get_frame_type call
pc_in_sigtramp has to re-do all the computation each time it is called
(typically duplicating the effort of get_frame_type)

- uses !frame_id_eq
Which is a 100% robust frame-changed test. The old test couldn't detect
a signal trampoline calling (via a signal) a singnal trampoline.

thoughts?

I'll look to commit this in a few days (already committed to my
trad-frame branch).

Andrew

[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 2005 bytes --]

2004-03-16 Andrew Cagney <cagney@redhat.com>

* infrun.c (handle_inferior_event): For non legacy frames, use the
frame ID and frame type to identify a signal trampoline. Update
comments.

Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.140
diff -u -r1.140 infrun.c
--- infrun.c 15 Mar 2004 17:12:50 -0000 1.140
+++ infrun.c 16 Mar 2004 18:25:45 -0000
@@ -2521,22 +2521,19 @@
But we can update it every time we leave the step range. */
ecs->update_step_sp = 1;

- /* Did we just take a signal? */
- if (pc_in_sigtramp (stop_pc)
- && !pc_in_sigtramp (prev_pc)
- && INNER_THAN (read_sp (), step_sp))
+ /* Did we just step into a singal trampoline (either by stepping out
+ of a handler, or by taking a signal)? */
+ /* NOTE: cagney/2004-03-16: Replaced (except for legacy) a check for
+ "pc_in_sigtramp(stop_pc) != pc_in_sigtramp(step_pc)" with
+ frame_type == SIGTRAMP && !frame_id_eq. The latter is far more
+ robust as it will correctly handle nested signal trampolines. */
+ if (legacy_frame_p (current_gdbarch)
+ ? (pc_in_sigtramp (stop_pc)
+ && !pc_in_sigtramp (prev_pc)
+ && INNER_THAN (read_sp (), step_sp))
+ : (get_frame_type (get_current_frame ()) == SIGTRAMP_FRAME
+ && !frame_id_eq (get_frame_id (get_current_frame ()), step_frame_id)))
{
- /* We've just taken a signal; go until we are back to
- the point where we took it and one more. */
-
- /* Note: The test above succeeds not only when we stepped
- into a signal handler, but also when we step past the last
- statement of a signal handler and end up in the return stub
- of the signal handler trampoline. To distinguish between
- these two cases, check that the frame is INNER_THAN the
- previous one below. pai/1997-09-11 */
-
-
{
struct frame_id current_frame = get_frame_id (get_current_frame ());