From 3c26fbf06b194e426307ab1bafa40f2d11d5d96b Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 3 Jul 2013 23:29:06 -0400 Subject: [PATCH] Fix #9854. 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. --- src/apps/debugger/controllers/TeamDebugger.cpp | 12 ++++++++++++ src/apps/debugger/controllers/ThreadHandler.cpp | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 7885590568..d1a7780264 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -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: diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp b/src/apps/debugger/controllers/ThreadHandler.cpp index 2a84a5b444..b0525ae5a5 100644 --- a/src/apps/debugger/controllers/ThreadHandler.cpp +++ b/src/apps/debugger/controllers/ThreadHandler.cpp @@ -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: