From 69d9446d9afa135864b956ab2a17c65edbe514b8 Mon Sep 17 00:00:00 2001 From: Igor Kulaychuk Date: Fri, 4 May 2018 14:50:57 +0300 Subject: [PATCH] Fix Break All behavior in Visual Studio --- src/debug/netcoredbg/manageddebugger.cpp | 46 ++++++++++++++++++++++++++++++-- src/debug/netcoredbg/miprotocol.cpp | 5 +++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/debug/netcoredbg/manageddebugger.cpp b/src/debug/netcoredbg/manageddebugger.cpp index cc540f8..6652cc9 100644 --- a/src/debug/netcoredbg/manageddebugger.cpp +++ b/src/debug/netcoredbg/manageddebugger.cpp @@ -796,8 +796,50 @@ HRESULT ManagedDebugger::Pause() if (!m_pProcess) return E_FAIL; HRESULT Status = m_pProcess->Stop(0); - if (Status == S_OK) - m_protocol->EmitStoppedEvent(StoppedEvent(StopPause, 0)); + if (Status != S_OK) + return Status; + + // For Visual Studio, we have to report a thread ID in async stop event. + // We have to find a thread which has a stack frame with valid location in its stack trace. + std::vector threads; + GetThreads(threads); + + int lastStoppedId = GetLastStoppedThreadId(); + + // Reorder threads so that last stopped thread is checked first + for (size_t i = 0; i < threads.size(); ++i) + { + if (threads[i].id == lastStoppedId) + { + std::swap(threads[0], threads[i]); + break; + } + } + + // Now get stack trace for each thread and find a frame with valid source location. + for (const Thread& thread : threads) + { + int totalFrames = 0; + std::vector stackFrames; + + if (FAILED(GetStackTrace(thread.id, 0, 0, stackFrames, totalFrames))) + continue; + + for (const StackFrame& stackFrame : stackFrames) + { + if (stackFrame.source.IsNull()) + continue; + + StoppedEvent event(StopPause, thread.id); + event.frame = stackFrame; + m_protocol->EmitStoppedEvent(event); + + return Status; + } + } + + m_protocol->EmitStoppedEvent(StoppedEvent(StopPause, 0)); + return Status; } diff --git a/src/debug/netcoredbg/miprotocol.cpp b/src/debug/netcoredbg/miprotocol.cpp index 8c8a9fc..4907bad 100644 --- a/src/debug/netcoredbg/miprotocol.cpp +++ b/src/debug/netcoredbg/miprotocol.cpp @@ -471,7 +471,10 @@ void MIProtocol::EmitStoppedEvent(StoppedEvent event) } case StopPause: { - MIProtocol::Printf("*stopped,reason=\"interrupted\",stopped-threads=\"all\"\n"); + // When async break happens, this should be reason="interrupted". + // But MIEngine in Visual Studio accepts only reason="signal-received",signal-name="SIGINT". + MIProtocol::Printf("*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",thread-id=\"%i\",stopped-threads=\"all\",frame={%s}\n", + event.threadId, frameLocation.c_str()); return; } case StopEntry: -- 2.7.4