e012fe34cb
When multiple threads wish to report a tracing event to a debugger, both threads call ptracestop() and one thread will win the race to be the reporting thread (p->p_xthread). The debugger uses PT_LWPINFO with the process ID to determine which thread / LWP is reporting an event and the details of that event. This event is cleared as a side effect of the subsequent ptrace event that resumed the process (PT_CONTINUE, PT_STEP, etc.). However, ptrace() was clearing the event identified by the LWP ID passed to the resume request even if that wasn't the 'p_xthread'. This could result in clearing an event that had not yet been observed by the debugger and leaving the existing event for 'p_thread' pending so that it was reported a second time. Specifically, if the debugger stopped due to a software breakpoint in one thread, but then switched to another thread that was used to resume (e.g. if the user switched to a different thread and issued a step), the resume request (PT_STEP) cleared a pending event (if any) for the thread being stepped. However, the process immediately stopped and the first thread reported it's breakpoint event a second time. The debugger decremented the PC for "both" breakpoint events which resulted in the PC now pointing into the middle of an instruction (on x86) and a SIGILL fault when the process was resumed a second time. To fix, always clear the pending event for 'p_xthread' when resuming a process. ptrace() still honors the requested LWP ID when enabling single-stepping (PT_STEP) or setting a different PC (PT_CONTINUE). Reported by: GDB testsuite (gdb.threads/continue-pending-status.exp) Reviewed by: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D12794 |
||
---|---|---|
.. | ||
acl | ||
aio | ||
fifo | ||
file | ||
fs | ||
geom | ||
kern | ||
kqueue | ||
mac | ||
mqueue | ||
netinet | ||
netpfil | ||
opencrypto | ||
pjdfstest | ||
posixshm | ||
sys | ||
vfs | ||
vm | ||
Makefile | ||
Makefile.depend | ||
Makefile.inc |