Skip to content

Commit cabe26f

Browse files
committed
fix: Target Process may crash on detaching process
1 parent 34f8fbd commit cabe26f

File tree

2 files changed

+30
-17
lines changed

2 files changed

+30
-17
lines changed

lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,13 @@ void DebuggerThread::DebugLoop() {
239239
BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
240240
if (wait_result) {
241241
DWORD continue_status = DBG_CONTINUE;
242+
bool shutting_down = m_is_shutting_down;
242243
switch (dbe.dwDebugEventCode) {
243244
default:
244245
llvm_unreachable("Unhandle debug event code!");
245246
case EXCEPTION_DEBUG_EVENT: {
246-
ExceptionResult status =
247-
HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
247+
ExceptionResult status = HandleExceptionEvent(
248+
dbe.u.Exception, dbe.dwThreadId, shutting_down);
248249

249250
if (status == ExceptionResult::MaskException)
250251
continue_status = DBG_CONTINUE;
@@ -292,6 +293,25 @@ void DebuggerThread::DebugLoop() {
292293

293294
::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
294295

296+
// We have to DebugActiveProcessStop after ContinueDebugEvent, otherwise
297+
// the target process will crash
298+
if (shutting_down) {
299+
// A breakpoint that occurs while `m_pid_to_detach` is non-zero is a
300+
// magic exception that we use simply to wake up the DebuggerThread so
301+
// that we can close out the debug loop.
302+
if (m_pid_to_detach != 0 &&
303+
(dbe.u.Exception.ExceptionRecord.ExceptionCode ==
304+
EXCEPTION_BREAKPOINT ||
305+
dbe.u.Exception.ExceptionRecord.ExceptionCode ==
306+
STATUS_WX86_BREAKPOINT)) {
307+
LLDB_LOG(log,
308+
"Breakpoint exception is cue to detach from process {0:x}",
309+
m_pid_to_detach.load());
310+
::DebugActiveProcessStop(m_pid_to_detach);
311+
m_detached = true;
312+
}
313+
}
314+
295315
if (m_detached) {
296316
should_debug = false;
297317
}
@@ -310,25 +330,18 @@ void DebuggerThread::DebugLoop() {
310330

311331
ExceptionResult
312332
DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
313-
DWORD thread_id) {
333+
DWORD thread_id, bool shutting_down) {
314334
Log *log = GetLog(WindowsLog::Event | WindowsLog::Exception);
315-
if (m_is_shutting_down) {
316-
// A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
317-
// exception that
318-
// we use simply to wake up the DebuggerThread so that we can close out the
319-
// debug loop.
320-
if (m_pid_to_detach != 0 &&
335+
if (shutting_down) {
336+
bool is_breakpoint =
321337
(info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT ||
322-
info.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT)) {
323-
LLDB_LOG(log, "Breakpoint exception is cue to detach from process {0:x}",
324-
m_pid_to_detach.load());
325-
::DebugActiveProcessStop(m_pid_to_detach);
326-
m_detached = true;
327-
}
338+
info.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT);
328339

329340
// Don't perform any blocking operations while we're shutting down. That
330341
// will cause TerminateProcess -> WaitForSingleObject to time out.
331-
return ExceptionResult::SendToApplication;
342+
// We should not send breakpoint exceptions to the application.
343+
return is_breakpoint ? ExceptionResult::MaskException
344+
: ExceptionResult::SendToApplication;
332345
}
333346

334347
bool first_chance = (info.dwFirstChance != 0);

lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
4646
void FreeProcessHandles();
4747
void DebugLoop();
4848
ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
49-
DWORD thread_id);
49+
DWORD thread_id, bool shutting_down);
5050
DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
5151
DWORD thread_id);
5252
DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,

0 commit comments

Comments
 (0)