This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 3/8] Deliver signal in hardware single step


Pedro Alves <palves@redhat.com> writes:

Hi Pedro,

> - If there's a signal handler installed, we'll stop at its entry,
>   but we haven't stepped over the original breakpoint yet.  If we
>   were already stopped at the entry of the signal handler, and it
>   nested, we'll find the program stopped at the same PC it had
>   started at.  But we won't know whether the step-over finished
>   successfully (could be a "jmp $pc" instruction), or if instead we're
>   in a new handler invocation, and thus this is a new,
>   separate breakpoint hit.

GDBserver doesn't have to tell the program stopped at the same PC
it had started at when step over is finished.  When step over, GDBserver
uninsert breakpoint, resumes the lwp, and wait the next event from the
lwp.  Once the event from the lwp arrives, GDBserver reinsert breakpoint
and thinks step over is finished.  That is all ...

>
>   A signal handler that segfaults in the first instruction
>   would be the easiest way to reproduce this that I can think of.
>   (If it's crashing, you'd expect the user might try putting a
>   breakpoint there.)

I write a case like this, set the conditional breakpoint on the first
instruction of handler, and looks breakpoint condition in target side
still works properly.

(gdb) disassemble handler
Dump of assembler code for function handler:
   0x0000000000400586 <+0>:     movb   $0x0,0x0
   0x000000000040058e <+8>:     retq

(gdb) p/x $rsp
$1 = 0x7fffffffde00
(gdb) b *handler if $rsp < 0x7fffffffde00 - 3300

the condition like this can guarantee that the condition will be true
after several recursions.

>
>   Now, if after stepping into the handler, we immediately reinsert the 
>   breakpoint and continue, we'll retrap it, it ends up OK.

breakpoint is reinserted after stepping into the handler, because
GDBserver thinks step over is finished, as I said above.

>   But if we immediately instead start a new step-over for the same 
>   breakpoint address, we will miss the new hit, and nest a new handler,
>   on and on.

This won't happen.  After hardware single step with signal delivered,
the program stops at the entry of handler, and GDBserver gets an event.
Then, GDBserver thinks step over is finished, and then proceed all lwps.
However, the thread still stopped at the breakpoint (of different
stack frames), so it needs step over again.  The loop like this will go
on until the breakpoint condition is true, need_step_over_p decides to
resume rather than step over.  The program will hit the breakpoint, and
GDBserver reports the event back to GDB.

Note in my experiment with the test case above, I don't let GDBserver
treat SIGSEGV as SIGTRAP, otherwise SIGSEGV will be reported back to GDB.

-- 
Yao (éå)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]