From: Pedro Alves <palves@redhat.com>
To: Yao Qi <qiyaoltc@gmail.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 3/8] Deliver signal in hardware single step
Date: Thu, 17 Mar 2016 12:12:00 -0000 [thread overview]
Message-ID: <56EA9F45.7050409@redhat.com> (raw)
In-Reply-To: <86io0mya1n.fsf@gmail.com>
On 03/16/2016 10:47 AM, Yao Qi wrote:
> 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.
>
OK.
We need to think of unconditional tracepoints as well,
not just conditional breakpoints, however.
Here's a likely scenario, that I think will happen:
#1 - tracepoint set at 0xf00.
#2 - Program stops at 0xf00, tracepoint is collected.
#3 - gdbserver starts a step-over
#4 - instead, a signal arrives, step-over cancelled.
#5 - signal should be passed, not reported to gdb.
#6 - gdbserver starts a new step-over, passing signal as well.
#7 - step lands in handler. step over finished.
#8 - gdbserver proceeds/continues
#9 - signal handler returns, again to 0xf00, tracepoint
traps again and is thus collected again. This is a
spurious collection.
gdb avoids the spurious double-hit in #9 by remembering that
it was stepping over a breakpoint when a signal arrived, in
order to continue the step over once the handler returns
(tp->step_after_step_resume_breakpoint). This only works if the handler
doesn't cause some other unrelated user-visible stop -- in that case,
then the next time the user continues the program, and the
handler returns to the original breakpoint address, we'll still
report a new breakpoint hit. I think.
Maybe we can just not bother and live with the spurious double
tracepoint hit/collect in gdbserver. (Likewise dprintf.)
Dunno, but I'm now starting to lean toward that.
Thanks,
Pedro Alves
next prev parent reply other threads:[~2016-03-17 12:12 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-04 10:44 [PATCH 0/8] Step over instruction branches to itself Yao Qi
2016-03-04 10:44 ` [PATCH 7/8] Resume the inferior with signal rather than stepping over Yao Qi
2016-03-11 12:04 ` Pedro Alves
2016-03-21 9:40 ` Yao Qi
2016-03-04 10:44 ` [PATCH 4/8] Force to insert software single step breakpoint Yao Qi
2016-03-11 11:49 ` Pedro Alves
2016-03-16 11:47 ` Yao Qi
2016-03-17 12:40 ` Pedro Alves
2016-03-18 14:25 ` Yao Qi
2016-03-18 15:03 ` Pedro Alves
2016-03-04 10:44 ` [PATCH 6/8] [GDBserver] Don't error in reinsert_raw_breakpoint if bp->inserted Yao Qi
2016-03-04 10:44 ` [PATCH 2/8] Check LWP_SIGNAL_CAN_BE_DELIVERED for enqueue/dequeue pending signals Yao Qi
2016-03-11 10:55 ` Pedro Alves
2016-03-17 8:40 ` Yao Qi
2016-03-17 11:07 ` Pedro Alves
2016-03-18 14:36 ` Yao Qi
2016-03-16 17:02 ` Luis Machado
2016-03-04 10:44 ` [PATCH 3/8] Deliver signal in hardware single step Yao Qi
2016-03-11 11:05 ` Pedro Alves
2016-03-11 11:09 ` Pedro Alves
2016-03-11 11:37 ` Pedro Alves
2016-03-16 10:47 ` Yao Qi
2016-03-17 12:12 ` Pedro Alves [this message]
2016-03-04 10:44 ` [PATCH 1/8] Set signal to 0 after enqueue_pending_signal Yao Qi
2016-03-11 10:53 ` Pedro Alves
2016-03-18 14:36 ` Yao Qi
2016-03-04 10:45 ` [PATCH 5/8] Insert breakpoint even when the raw breakpoint is found Yao Qi
2016-03-11 11:54 ` Pedro Alves
2016-03-04 10:45 ` [PATCH 8/8] New test case gdb.base/branch-to-self.exp Yao Qi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56EA9F45.7050409@redhat.com \
--to=palves@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=qiyaoltc@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).