Merge topic 'debugger-segfault' into release-3.27

764258771a Debugger: Fix threads request segfault after thread exited event

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !8604
This commit is contained in:
Brad King
2023-06-30 13:30:02 +00:00
committed by Kitware Robot
2 changed files with 39 additions and 5 deletions

View File

@@ -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;
});

View File

@@ -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,
});
}