Skip to content

Commit e427e93

Browse files
authored
[lldb][dap] Avoid concurrent HandleCommand calls (llvm#83162)
The `EventThreadFunction` can end up calling `HandleCommand` concurrently with the main request processing thread. The underlying API does not appear to be thread safe, so add a narrowly scoped mutex lock to prevent calling it in this place from more than one thread. Fixes llvm#81686. Prior to this, TestDAP_launch.py is 4% flaky. After, it passes in 1000 runs.
1 parent 563f414 commit e427e93

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import os
2-
import unittest
32

43
import dap_server
54
import lldbdap_testcase
65
from lldbsuite.test import lldbtest, lldbutil
76
from lldbsuite.test.decorators import *
87

98

10-
@unittest.skip("https://llvm.org/PR81686")
119
class TestDAP_commands(lldbdap_testcase.DAPTestCaseBase):
1210
def test_command_directive_quiet_on_success(self):
1311
program = self.getBuildArtifact("a.out")

lldb/tools/lldb-dap/LLDBUtils.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "LLDBUtils.h"
1010
#include "DAP.h"
1111

12+
#include <mutex>
13+
1214
namespace lldb_dap {
1315

1416
bool RunLLDBCommands(llvm::StringRef prefix,
@@ -37,7 +39,15 @@ bool RunLLDBCommands(llvm::StringRef prefix,
3739
}
3840
}
3941

40-
interp.HandleCommand(command.str().c_str(), result);
42+
{
43+
// Prevent simultaneous calls to HandleCommand, e.g. EventThreadFunction
44+
// may asynchronously call RunExitCommands when we are already calling
45+
// RunTerminateCommands.
46+
static std::mutex handle_command_mutex;
47+
std::lock_guard<std::mutex> locker(handle_command_mutex);
48+
interp.HandleCommand(command.str().c_str(), result);
49+
}
50+
4151
const bool got_error = !result.Succeeded();
4252
// The if statement below is assuming we always print out `!` prefixed
4353
// lines. The only time we don't print is when we have `quiet_on_success ==

0 commit comments

Comments
 (0)