The post syscall debug events used for output capture have an
unfortunate side effect: when asked to debug a thread, the thread is
interrupted, which, if currently blocked in a syscall will cause it to
unblock and send a post syscall event indicating such. However, this
will also absorb the debug stop flag that was set by the initial debug
request, and so we won't actually get the separate event indicating
thread debugged.

Consequently, we now set a pending stop request flag on the
corresponding Thread object, and check if it's set when processing
syscall events. If so, we treat such an event as having triggered a
debug stop even though the received event type is not explicitly
B_DEBUGGER_MESSAGE_THREAD_DEBUGGED.
This commit is contained in:
Rene Gollent
2013-07-04 07:39:42 -04:00
parent cc6b4a3cb1
commit 3c26fbf06b
2 changed files with 15 additions and 2 deletions
@@ -1270,6 +1270,18 @@ TeamDebugger::_HandleDebuggerMessage(DebugEvent* event)
TRACE_EVENTS("B_DEBUGGER_MESSAGE_POST_SYSCALL: syscall: %"
B_PRIu32 "\n", postSyscallEvent->GetSyscallInfo().Syscall());
handled = _HandlePostSyscall(postSyscallEvent);
// if a thread was blocked in a syscall when we requested to
// stop it for debugging, then that request will interrupt
// said call, and the post syscall event will be all we get
// in response. Consequently, we need to treat this case as
// equivalent to having received a thread debugged event.
AutoLocker< ::Team> teamLocker(fTeam);
::Thread* thread = fTeam->ThreadByID(event->Thread());
if (handler != NULL && thread != NULL
&& thread->StopRequestPending()) {
handled = handler->HandleThreadDebugged(NULL);
}
break;
}
case B_DEBUGGER_MESSAGE_PRE_SYSCALL:
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2010-2011, Rene Gollent, rene@gollent.com.
* Copyright 2010-2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@@ -243,7 +243,8 @@ ThreadHandler::HandleThreadAction(uint32 action, target_addr_t address)
return;
case MSG_THREAD_STOP:
fStepMode = STEP_NONE;
fDebuggerInterface->StopThread(ThreadID());
if (fDebuggerInterface->StopThread(ThreadID()) == B_OK)
fThread->SetStopRequestPending();
return;
case MSG_THREAD_STEP_OVER:
case MSG_THREAD_STEP_INTO: