yinghuitan updated this revision to Diff 468591.
yinghuitan added a comment.
Use async model.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D135798/new/
https://reviews.llvm.org/D135798
Files:
lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
lldb/tools/lldb-vscode/VSCode.cpp
lldb/tools/lldb-vscode/VSCode.h
lldb/tools/lldb-vscode/lldb-vscode.cpp
lldb/tools/lldb-vscode/package.json
Index: lldb/tools/lldb-vscode/package.json
===================================================================
--- lldb/tools/lldb-vscode/package.json
+++ lldb/tools/lldb-vscode/package.json
@@ -157,6 +157,11 @@
"description": "Automatically stop after launch.",
"default": false
},
+ "runToBinaryEntry": {
+ "type": "boolean",
+ "description": "run to program entry one-shot breakpoint during launch to ensure dependency modules are loaded.",
+ "default": false
+ },
"disableASLR": {
"type": "boolean",
"description": "Enable or disable Address space layout randomization if the debugger supports it.",
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1610,6 +1610,68 @@
error.GetCString());
}
+lldb::SBError RunToBinaryEntry() {
+ lldb::SBError error;
+ if (!g_vsc.run_to_binary_entry)
+ return error;
+
+ if (g_vsc.stop_at_entry) {
+ g_vsc.SendOutput(OutputType::Console,
+ "RunToBinaryEntry is ignored due to StopOnEntry\n");
+ return error;
+ }
+
+ lldb::SBTarget target = g_vsc.debugger.GetSelectedTarget();
+ if (!target.IsValid())
+ return error;
+ lldb::SBFileSpec exe_file = target.GetExecutable();
+ if (!exe_file.IsValid())
+ return error;
+ lldb::SBModule exe_module = target.FindModule(exe_file);
+ if (!exe_module.IsValid()) {
+ g_vsc.SendOutput(OutputType::Console,
+ "RunToBinaryEntry failed: invalid executable module\n");
+ return error;
+ }
+
+ lldb::SBAddress entry_point = exe_module.GetObjectFileEntryPointAddress();
+ if (!entry_point.IsValid()) {
+ g_vsc.SendOutput(OutputType::Console,
+ "RunToBinaryEntry failed: can't find entry point\n");
+ return error;
+ }
+ lldb::SBBreakpoint entry_breakpoint =
+ target.BreakpointCreateBySBAddress(entry_point);
+ if (!entry_breakpoint.IsValid() || entry_breakpoint.GetNumLocations() == 0) {
+ g_vsc.SendOutput(OutputType::Console,
+ "RunToBinaryEntry failed: can't place the breakpoint\n");
+ return error;
+ }
+
+ uint32_t old_stop_id = target.GetProcess().GetStopID();
+ entry_breakpoint.SetOneShot(true);
+ error = target.GetProcess().Continue();
+ if (error.Fail())
+ return error;
+
+ const uint64_t timeout_seconds = 600;
+ error = g_vsc.WaitForProcessToStop(timeout_seconds, old_stop_id);
+ if (error.Fail())
+ return error;
+
+ // Successfully got a process stop; we still need to check if the stop is what
+ // we expected.
+ if (entry_breakpoint.GetHitCount() == 0)
+ g_vsc.SendOutput(OutputType::Telemetry,
+ "RunToBinaryEntry failed: process stopped not at the "
+ "binary's entry point\n");
+ else
+ g_vsc.SendOutput(OutputType::Telemetry,
+ "RunToBinaryEntry success: Process stopped successfully "
+ "at the binary's entry point\n");
+ return error;
+}
+
// "LaunchRequest": {
// "allOf": [ { "$ref": "#/definitions/Request" }, {
// "type": "object",
@@ -1659,6 +1721,7 @@
std::vector<std::string> postRunCommands =
GetStrings(arguments, "postRunCommands");
g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
+ g_vsc.run_to_binary_entry = GetBoolean(arguments, "runToBinaryEntry", false);
const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
@@ -1741,6 +1804,9 @@
error = g_vsc.WaitForProcessToStop(timeout_seconds);
}
+ if (error.Success())
+ error = RunToBinaryEntry();
+
if (error.Fail()) {
response["success"] = llvm::json::Value(false);
EmplaceSafeString(response, "message", std::string(error.GetCString()));
Index: lldb/tools/lldb-vscode/VSCode.h
===================================================================
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -144,6 +144,7 @@
lldb::tid_t focus_tid;
bool sent_terminated_event;
bool stop_at_entry;
+ bool run_to_binary_entry = false;
bool is_attach;
bool configuration_done_sent;
uint32_t reverse_request_seq;
@@ -261,9 +262,14 @@
///
/// \param[in] seconds
/// The number of seconds to poll the process to wait until it is stopped.
+ /// \param[in] old_stop_id
+ /// Optional old stop id which we should only check for stopped state if
+ /// the new stop id is greater than it. This is needed if the previous state
+ /// is stopped so that we can ensure we are checking new stopped state not
+ /// the old one in async mode.
///
/// \return Error if waiting for the process fails, no error if succeeds.
- lldb::SBError WaitForProcessToStop(uint32_t seconds);
+ lldb::SBError WaitForProcessToStop(uint32_t seconds, uint32_t old_stop_id = 0);
private:
// Send the JSON in "json_str" to the "out" stream. Correctly send the
Index: lldb/tools/lldb-vscode/VSCode.cpp
===================================================================
--- lldb/tools/lldb-vscode/VSCode.cpp
+++ lldb/tools/lldb-vscode/VSCode.cpp
@@ -528,7 +528,7 @@
request_handlers[request] = callback;
}
-lldb::SBError VSCode::WaitForProcessToStop(uint32_t seconds) {
+lldb::SBError VSCode::WaitForProcessToStop(uint32_t seconds, uint32_t old_stop_id) {
lldb::SBError error;
lldb::SBProcess process = target.GetProcess();
if (!process.IsValid()) {
@@ -538,6 +538,10 @@
auto timeout_time =
std::chrono::steady_clock::now() + std::chrono::seconds(seconds);
while (std::chrono::steady_clock::now() < timeout_time) {
+ // Wait for stop id changed before checking for stopped state.
+ // This is needed to ensure we are checking old stopped state in async mode.
+ if (old_stop_id > 0 && process.GetStopID() <= old_stop_id)
+ continue;
const auto state = process.GetState();
switch (state) {
case lldb::eStateAttaching:
Index: lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
===================================================================
--- lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
+++ lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
@@ -78,6 +78,29 @@
reason != 'breakpoint',
'verify stop isn\'t "main" breakpoint')
+ @skipIfWindows
+ @skipIfRemote
+ def test_runToBinaryEntry(self):
+ '''
+ Tests the runToBinaryEntry option can successfully launch a simple
+ program and hit a breakpoint and does not interupt the launch.
+ '''
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program, runToBinaryEntry=True)
+ self.set_function_breakpoints(['main'])
+ stopped_events = self.continue_to_next_stop()
+ console_output = self.get_console()
+ self.assertIn("Process stopped successfully at the binary's entry point", console_output)
+
+ for stopped_event in stopped_events:
+ if 'body' in stopped_event:
+ body = stopped_event['body']
+ if 'reason' in body:
+ reason = body['reason']
+ self.assertTrue(
+ reason == 'breakpoint',
+ 'verify successfully stop at "main" breakpoint')
+
@skipIfWindows
@skipIfRemote
def test_cwd(self):
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
@@ -644,7 +644,7 @@
terminateCommands=None ,sourcePath=None,
debuggerRoot=None, launchCommands=None, sourceMap=None,
runInTerminal=False, expectFailure=False,
- postRunCommands=None):
+ postRunCommands=None, runToBinaryEntry=False):
args_dict = {
'program': program
}
@@ -656,6 +656,8 @@
args_dict['env'] = env
if stopOnEntry:
args_dict['stopOnEntry'] = stopOnEntry
+ if runToBinaryEntry:
+ args_dict['runToBinaryEntry'] = runToBinaryEntry
if disableASLR:
args_dict['disableASLR'] = disableASLR
if disableSTDIO:
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
@@ -286,7 +286,7 @@
stopCommands=None, exitCommands=None, terminateCommands=None,
sourcePath=None, debuggerRoot=None, sourceInitFile=False, launchCommands=None,
sourceMap=None, disconnectAutomatically=True, runInTerminal=False,
- expectFailure=False, postRunCommands=None):
+ expectFailure=False, postRunCommands=None, runToBinaryEntry=False):
'''Sending launch request to vscode
'''
@@ -323,7 +323,8 @@
sourceMap=sourceMap,
runInTerminal=runInTerminal,
expectFailure=expectFailure,
- postRunCommands=postRunCommands)
+ postRunCommands=postRunCommands,
+ runToBinaryEntry=runToBinaryEntry)
if expectFailure:
return response
@@ -346,7 +347,7 @@
terminateCommands=None, sourcePath=None,
debuggerRoot=None, sourceInitFile=False, runInTerminal=False,
disconnectAutomatically=True, postRunCommands=None,
- lldbVSCodeEnv=None):
+ lldbVSCodeEnv=None, runToBinaryEntry=False):
'''Build the default Makefile target, create the VSCode debug adaptor,
and launch the process.
'''
@@ -359,4 +360,5 @@
terminateCommands, sourcePath, debuggerRoot, sourceInitFile,
runInTerminal=runInTerminal,
disconnectAutomatically=disconnectAutomatically,
- postRunCommands=postRunCommands)
+ postRunCommands=postRunCommands,
+ runToBinaryEntry=runToBinaryEntry)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits