Debugger: Fix threads request segfault after thread exited event
Fixes: #25041stage/master/nightly/2023/06/30^2
parent
7952e11466
commit
764258771a
|
@ -167,10 +167,16 @@ cmDebuggerAdapter::cmDebuggerAdapter(
|
|||
(void)req;
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
dap::ThreadsResponse response;
|
||||
dap::Thread thread;
|
||||
thread.id = DefaultThread->GetId();
|
||||
thread.name = DefaultThread->GetName();
|
||||
response.threads.push_back(thread);
|
||||
|
||||
// If a client requests threads during shutdown (like after receiving the
|
||||
// thread exited event), DefaultThread won't be set.
|
||||
if (DefaultThread) {
|
||||
dap::Thread thread;
|
||||
thread.id = DefaultThread->GetId();
|
||||
thread.name = DefaultThread->GetName();
|
||||
response.threads.push_back(thread);
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
std::shared_ptr<dap::ReaderWriter> DebuggerToClient;
|
||||
};
|
||||
|
||||
bool testBasicProtocol()
|
||||
bool runTest(std::function<bool(dap::Session&)> onThreadExitedEvent)
|
||||
{
|
||||
std::promise<bool> debuggerAdapterInitializedPromise;
|
||||
std::future<bool> debuggerAdapterInitializedFuture =
|
||||
|
@ -152,6 +152,11 @@ bool testBasicProtocol()
|
|||
std::future_status::ready);
|
||||
ASSERT_TRUE(threadExitedFuture.wait_for(futureTimeout) ==
|
||||
std::future_status::ready);
|
||||
|
||||
if (onThreadExitedEvent) {
|
||||
ASSERT_TRUE(onThreadExitedEvent(*client));
|
||||
}
|
||||
|
||||
ASSERT_TRUE(exitedEventReceivedFuture.wait_for(futureTimeout) ==
|
||||
std::future_status::ready);
|
||||
ASSERT_TRUE(terminatedEventReceivedFuture.wait_for(futureTimeout) ==
|
||||
|
@ -165,9 +170,32 @@ bool testBasicProtocol()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool testBasicProtocol()
|
||||
{
|
||||
return runTest(nullptr);
|
||||
}
|
||||
|
||||
bool testThreadsRequestAfterThreadExitedEvent()
|
||||
{
|
||||
return runTest([](dap::Session& session) -> bool {
|
||||
// Try requesting threads again after receiving the thread exited event.
|
||||
// Some clients do this to ensure that their thread list is up-to-date.
|
||||
dap::ThreadsRequest threadsRequest;
|
||||
auto threadsResponse = session.send(threadsRequest).get();
|
||||
ASSERT_TRUE(!threadsResponse.error);
|
||||
|
||||
// CMake only has one DAP thread. Once that thread exits, there should be
|
||||
// no threads left.
|
||||
ASSERT_TRUE(threadsResponse.response.threads.empty());
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
int testDebuggerAdapter(int, char*[])
|
||||
{
|
||||
return runTests(std::vector<std::function<bool()>>{
|
||||
testBasicProtocol,
|
||||
testThreadsRequestAfterThreadExitedEvent,
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue