Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [patch/rfc] Use frame_type for sigtramp test in infrun.c
@ 2004-03-29 23:38 Ulrich Weigand
  2004-03-31 21:49 ` Andrew Cagney
  2004-04-02 20:50 ` Andrew Cagney
  0 siblings, 2 replies; 16+ messages in thread
From: Ulrich Weigand @ 2004-03-29 23:38 UTC (permalink / raw)
  To: cagney; +Cc: gdb-patches

Andrew Cagney wrote:

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

This breaks signals.exp on s390 again.

What now happens is the following:

- we are in main and do 'next'; step_frame_id is set to the current frame
- gdb starts single-stepping
- in the meantime, a signal has arrived and the kernel invokes the handler
  Note that the kernel directly jumps to the handler, and sets up the
  return address to point to the signal return trampoline.
- gdb single-steps and stops on the first instruction of the handler
  at this point, the call-chain is
    handler
    <signal trampoline>
    main
- gdb thinks it has stepped into a subroutine, and does
  handle_step_into_function, which calls keep_going
- keep_going saves the current pc (i.e. start of handler) into prev_pc
- we run until the return from handler, i.e. we stop on the first
  (and only) instruction of the signal trampoline
- now the 'if' you changed hits because we are in fact in a signal trampoline
  frame. 
- within the if, there's a second if that tries to distiguish between
  stepping into a trampoline before the signal handler from one after
  the signal handler.  This is attempted via
    if (frame_id_inner (current_frame, step_frame_id))
- unfortunately, step_frame_id is still the frame of 'main', and thus
  the current (i.e. trampoline) frame *is* 'inner', even though we
  actually have a trampoline after, not before the handler.
- gdb now does
            sr_sal.line = 0;
            sr_sal.pc = prev_pc;
            /* We could probably be setting the frame to
               step_frame_id; I don't think anyone thought to try it.  */
            check_for_old_step_resume_breakpoint ();
            step_resume_breakpoint =
              set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
  However, prev_pc was set to first instruction of handler above
- since we never again enter the handler, the breakpoint is never hit
  and we run until the end of main


I'm not sure what the correct way to fix this issue would be.

However, simply removing the whole 'if' block makes signals.exp pass on s390.
This is because both the handler and the signal return trampoline are now
simply treated as calls into subroutines, and both are skipped with
step_over_function, so that everything works just as expected.

Why is this if needed in the first place?  Isn't this just to work around
frame problems that caused step_over_function to not handle signal handlers
correctly?  I.e. if we have new-style frames that work properly, can't we
just skip that whole if?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


^ permalink raw reply	[flat|nested] 16+ messages in thread
* [patch/rfc] Use frame_type for sigtramp test in infrun.c
@ 2004-03-16 18:57 Andrew Cagney
  2004-03-19  0:09 ` Andrew Cagney
  2004-03-21 22:38 ` Andrew Cagney
  0 siblings, 2 replies; 16+ messages in thread
From: Andrew Cagney @ 2004-03-16 18:57 UTC (permalink / raw)
  To: gdb-patches

[-- 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 ());
 

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2004-04-29 22:46 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-29 23:38 [patch/rfc] Use frame_type for sigtramp test in infrun.c Ulrich Weigand
2004-03-31 21:49 ` Andrew Cagney
2004-04-02 20:50 ` Andrew Cagney
2004-04-02 23:57   ` Joel Brobecker
2004-04-03  0:08   ` Joel Brobecker
2004-04-03  1:01     ` Andrew Cagney
2004-04-06  1:48       ` Joel Brobecker
2004-04-06 16:21         ` Joel Brobecker
2004-04-06 17:48           ` Andrew Cagney
2004-04-06 17:54             ` Daniel Jacobowitz
2004-04-06 18:11               ` Andrew Cagney
2004-04-06 23:33                 ` Andrew Cagney
2004-04-29 22:46         ` Andrew Cagney
  -- strict thread matches above, loose matches on Subject: below --
2004-03-16 18:57 Andrew Cagney
2004-03-19  0:09 ` Andrew Cagney
2004-03-21 22:38 ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox