Hi Roland, Oleg

I hit upon a case where a traced thread steps over a inserted breakpoint
instruction, and the tracing engine requests the traced thread to be
interrupted. Here the traced thread calls report_signal callback with
UTRACE_REPORT_SIGNAL and later does a report_signal callback with
UTRACE_SIGNAL_CORE. 

We do have a comment in utrace_get_signal() which does indicate the
behaviour I see. 
/*
 * We've been asked for an explicit report before we
 * even check for pending signals.
 */

However I was looking if there were reasons why "interrupt" from a
tracing thread would be preferred over a "queued signal"?

I am seeing this situation in Uprobes. 

A uprobes enabled tracer wanted to remove a breakpoint and hence
requested the thread to stop using utrace_control with action being
UTRACE_STOP. Since utrace_control returns -EINPROGRESS, and thread state
_not_ being in TASK_INTERRUPTIBLE state, the tracer requests for
utrace_control with action this time being UTRACE_INTERRUPT. Right at
this time, the tracing thread steps over the trap.  This causes
uprobe_report_signal() to be called with signal_action ==
UTRACE_SIGNAL_REPORT instead of (say) UTRACE_SIGNAL_CORE. Now tracer is
able to remove the breakpoint. However on resuming the thread sees that
it has a signal pending and delivers the signal, this time lets say
action is UTRACE_SIGNAL_CORE. Since uprobes doesnt see a breakpoint
there, it resumes. However resuming after stepping a breakpoint but
without fix-ups could lead to disastrous results.

Currently we do have a way in uprobes to handle this situation. i.e to
check if any threads have stepped on breakpoint instruction related to
the breakpoint that we are removing and if there are any such threads
then fixup their Instruction Pointers.

--
Thanks and Regards
Srikar 

Reply via email to