[commit] Increase priority of step-resume breakpoints

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

[commit] Increase priority of step-resume breakpoints

Daniel Jacobowitz-2
I spent a while yesterday trying to debug qemu-system-arm using GDB.
The problem with this is that it uses SIGALRM to simulate a 1ms timer.
That means that any time GDB stops qemu, there's a pending SIGALRM, so
it's a heavy workout on the signal handling paths.  It also means that
if GDB takes longer than 1ms to redeliver the SIGALRM; detect entrance
into the signal handler; set a step resume breakpoint; resume; detect
the step resume breakpoint; remove it; and repeat the earlier step or
continue, then GDB makes no progress - qemu spins in place and no work
is done.  Just waiting, detecting the SIGALRM, and forwarding it we
can handle in <1ms, so the program can run.  But when you hit a
breakpoint of any kind, you're pretty much stuck.

1ms is basically an unrealistic goal even on a 2.4GHz AMD64 system.
There's too much signal handling latency even if GDB were much more
efficient than it actually is.  That's only enough time for a few
dozen syscalls, and context switches make it even worse.  So
eventually I ended up doing the same thing as last time I needed to do
this: I slowed down the timer.  Some day when I have more time to
spend, I'd love to see if I can get GDB to meet this goal.

An alternative solution would be an OS interface to let GDB block
signals (we could delay the SIGALRM until after the single step
completed).  It might even work to manually delay the signal in GDB,
but I'm not sure if the OS would try to deliver the next pending timer
too soon in that case.

But before I gave up I investigated the worst offender.  The first
breakpoint we hit was a shared library breakpoint, when qemu dlopens
something related to SDL.  We hit the shared library breakpoint,
handled it, tried to step off the breakpoint, got a signal, inserted a
step-resume breakpoint, let qemu tear through the signal handler,
and hit the step-resume breakpoint.  It just so happens that the
step resume breakpoint and shared library event breakpoint were at the
same place.  So we tried to handle the shared library events a second
time, which is of course quite slow as we dredge through inferior memory.
That's silly; if we hit a step-resume breakpoint, it means we've been
here before.  So this patch bumps the ordering of the step-resume
breakpoint to the top.

Tested on x86_64-linux, by the testsuite and by visual inspection of
debug output while running qemu.  Checked in.

Daniel Jacobowitz

2007-04-13  Daniel Jacobowitz  <[hidden email]>

        * breakpoint.c (bpstat_what): Give step-resume higher priority than
        shlib events.

 breakpoint.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Index: breakpoint.c
--- breakpoint.c.orig 2007-04-13 09:08:43.000000000 -0400
+++ breakpoint.c 2007-04-13 09:09:58.000000000 -0400
@@ -3120,10 +3120,10 @@ bpstat_what (bpstat bs)
      clrs < err shl shlr sn sr ss ts
      ss   < shl shlr sn sr ts
      sn   < shl shlr sr ts
-     sr   < shl shlr ts
-     shl  < shlr
+     shl  < shlr sr
+     shlr < sr
+     sr   < ts
      ts   <
-     shlr <
      What I think this means is that we don't need a damned table
      here.  If you just put the rows and columns in the right order,
@@ -3160,13 +3160,13 @@ bpstat_what (bpstat bs)
 /*long_resume */
     {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
 /*step_resume */
-    {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl, shlr},
+    {sr, sr, sr, sr, sr, sr, sr, sr, ts, sr, sr},
 /*through_sig */
     {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl, shlr},
 /*shlib */
-    {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl, shlr},
+    {shl, shl, shl, shl, shl, shl, shl, sr, ts, shl, shlr},
 /*catch_shlib */
-    {shlr, shlr, shlr, shlr, shlr, shlr, shlr, shlr, ts, shlr, shlr}
+    {shlr, shlr, shlr, shlr, shlr, shlr, shlr, sr, ts, shlr, shlr}
 #undef kc