Redo of Add terminateCommands to lldb-vscode protocol
Summary: This redoes https://reviews.llvm.org/D79726 and fixes two things. - The logic that determines whether to automatically disconnect during the tear down is not very dumb compared to the original implementation. Each test will determine whether to do that or not. - The terminate commands and terminate event were being sent after the disconnect response was sent to the IDE. That was not good, as VSCode stops the debug session as soon as it receives a disconnect response. Now, the terminate event and terminateEvents are being executed before the disconnect response is sent. This ensures that any connection between the IDE and lldb-vscode is alive while the terminate commands are executed. Besides, it also allows displaying the output of the terminate commands on the debug console, as it's still alive. Reviewers: clayborg, aadsm, kusmour, labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D81978
This commit is contained in:
parent
33ece57241
commit
74ab1da028
|
@ -179,6 +179,9 @@ class VSCodeTestCaseBase(TestBase):
|
|||
def get_console(self, timeout=0.0):
|
||||
return self.vscode.get_output('console', timeout=timeout)
|
||||
|
||||
def collect_console(self, duration):
|
||||
return self.vscode.collect_output('console', duration=duration)
|
||||
|
||||
def get_local_as_int(self, name, threadId=None):
|
||||
value = self.vscode.get_local_variable_value(name, threadId=threadId)
|
||||
if value.startswith('0x'):
|
||||
|
@ -239,7 +242,8 @@ class VSCodeTestCaseBase(TestBase):
|
|||
|
||||
def attach(self, program=None, pid=None, waitFor=None, trace=None,
|
||||
initCommands=None, preRunCommands=None, stopCommands=None,
|
||||
exitCommands=None, attachCommands=None, coreFile=None, disconnectAutomatically=True):
|
||||
exitCommands=None, attachCommands=None, coreFile=None,
|
||||
disconnectAutomatically=True, terminateCommands=None):
|
||||
'''Build the default Makefile target, create the VSCode debug adaptor,
|
||||
and attach to the process.
|
||||
'''
|
||||
|
@ -258,7 +262,8 @@ class VSCodeTestCaseBase(TestBase):
|
|||
program=program, pid=pid, waitFor=waitFor, trace=trace,
|
||||
initCommands=initCommands, preRunCommands=preRunCommands,
|
||||
stopCommands=stopCommands, exitCommands=exitCommands,
|
||||
attachCommands=attachCommands, coreFile=coreFile)
|
||||
attachCommands=attachCommands, terminateCommands=terminateCommands,
|
||||
coreFile=coreFile)
|
||||
if not (response and response['success']):
|
||||
self.assertTrue(response['success'],
|
||||
'attach failed (%s)' % (response['message']))
|
||||
|
@ -267,15 +272,17 @@ class VSCodeTestCaseBase(TestBase):
|
|||
stopOnEntry=False, disableASLR=True,
|
||||
disableSTDIO=False, shellExpandArguments=False,
|
||||
trace=False, initCommands=None, preRunCommands=None,
|
||||
stopCommands=None, exitCommands=None,sourcePath=None,
|
||||
debuggerRoot=None, launchCommands=None, sourceMap=None):
|
||||
stopCommands=None, exitCommands=None, terminateCommands=None,
|
||||
sourcePath=None, debuggerRoot=None, launchCommands=None,
|
||||
sourceMap=None, disconnectAutomatically=True):
|
||||
'''Sending launch request to vscode
|
||||
'''
|
||||
|
||||
# Make sure we disconnect and terminate the VSCode debug adapter,
|
||||
# if we throw an exception during the test case
|
||||
def cleanup():
|
||||
self.vscode.request_disconnect(terminateDebuggee=True)
|
||||
if disconnectAutomatically:
|
||||
self.vscode.request_disconnect(terminateDebuggee=True)
|
||||
self.vscode.terminate()
|
||||
|
||||
# Execute the cleanup function during test case tear down.
|
||||
|
@ -297,6 +304,7 @@ class VSCodeTestCaseBase(TestBase):
|
|||
preRunCommands=preRunCommands,
|
||||
stopCommands=stopCommands,
|
||||
exitCommands=exitCommands,
|
||||
terminateCommands=terminateCommands,
|
||||
sourcePath=sourcePath,
|
||||
debuggerRoot=debuggerRoot,
|
||||
launchCommands=launchCommands,
|
||||
|
@ -310,7 +318,8 @@ class VSCodeTestCaseBase(TestBase):
|
|||
disableSTDIO=False, shellExpandArguments=False,
|
||||
trace=False, initCommands=None, preRunCommands=None,
|
||||
stopCommands=None, exitCommands=None,
|
||||
sourcePath=None, debuggerRoot=None):
|
||||
terminateCommands=None, sourcePath=None,
|
||||
debuggerRoot=None):
|
||||
'''Build the default Makefile target, create the VSCode debug adaptor,
|
||||
and launch the process.
|
||||
'''
|
||||
|
@ -320,4 +329,4 @@ class VSCodeTestCaseBase(TestBase):
|
|||
self.launch(program, args, cwd, env, stopOnEntry, disableASLR,
|
||||
disableSTDIO, shellExpandArguments, trace,
|
||||
initCommands, preRunCommands, stopCommands, exitCommands,
|
||||
sourcePath, debuggerRoot)
|
||||
terminateCommands, sourcePath, debuggerRoot)
|
||||
|
|
|
@ -10,6 +10,7 @@ import string
|
|||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
def dump_memory(base_addr, data, num_per_line, outfile):
|
||||
|
@ -148,6 +149,15 @@ class DebugCommunication(object):
|
|||
self.output_condition.release()
|
||||
return output
|
||||
|
||||
def collect_output(self, category, duration, clear=True):
|
||||
end_time = time.time() + duration
|
||||
collected_output = ""
|
||||
while end_time > time.time():
|
||||
output = self.get_output(category, timeout=0.25, clear=clear)
|
||||
if output:
|
||||
collected_output += output
|
||||
return collected_output if collected_output else None
|
||||
|
||||
def enqueue_recv_packet(self, packet):
|
||||
self.recv_condition.acquire()
|
||||
self.recv_packets.append(packet)
|
||||
|
@ -450,7 +460,8 @@ class DebugCommunication(object):
|
|||
def request_attach(self, program=None, pid=None, waitFor=None, trace=None,
|
||||
initCommands=None, preRunCommands=None,
|
||||
stopCommands=None, exitCommands=None,
|
||||
attachCommands=None, coreFile=None):
|
||||
attachCommands=None, terminateCommands=None,
|
||||
coreFile=None):
|
||||
args_dict = {}
|
||||
if pid is not None:
|
||||
args_dict['pid'] = pid
|
||||
|
@ -469,6 +480,8 @@ class DebugCommunication(object):
|
|||
args_dict['stopCommands'] = stopCommands
|
||||
if exitCommands:
|
||||
args_dict['exitCommands'] = exitCommands
|
||||
if terminateCommands:
|
||||
args_dict['terminateCommands'] = terminateCommands
|
||||
if attachCommands:
|
||||
args_dict['attachCommands'] = attachCommands
|
||||
if coreFile:
|
||||
|
@ -571,7 +584,8 @@ class DebugCommunication(object):
|
|||
stopOnEntry=False, disableASLR=True,
|
||||
disableSTDIO=False, shellExpandArguments=False,
|
||||
trace=False, initCommands=None, preRunCommands=None,
|
||||
stopCommands=None, exitCommands=None, sourcePath=None,
|
||||
stopCommands=None, exitCommands=None,
|
||||
terminateCommands=None ,sourcePath=None,
|
||||
debuggerRoot=None, launchCommands=None, sourceMap=None):
|
||||
args_dict = {
|
||||
'program': program
|
||||
|
@ -601,6 +615,8 @@ class DebugCommunication(object):
|
|||
args_dict['stopCommands'] = stopCommands
|
||||
if exitCommands:
|
||||
args_dict['exitCommands'] = exitCommands
|
||||
if terminateCommands:
|
||||
args_dict['terminateCommands'] = terminateCommands
|
||||
if sourcePath:
|
||||
args_dict['sourcePath'] = sourcePath
|
||||
if debuggerRoot:
|
||||
|
@ -905,7 +921,8 @@ def run_vscode(dbg, args, options):
|
|||
initCommands=options.initCmds,
|
||||
preRunCommands=options.preRunCmds,
|
||||
stopCommands=options.stopCmds,
|
||||
exitCommands=options.exitCmds)
|
||||
exitCommands=options.exitCmds,
|
||||
terminateCommands=options.terminateCmds)
|
||||
else:
|
||||
response = dbg.request_launch(options.program,
|
||||
args=args,
|
||||
|
@ -916,7 +933,8 @@ def run_vscode(dbg, args, options):
|
|||
initCommands=options.initCmds,
|
||||
preRunCommands=options.preRunCmds,
|
||||
stopCommands=options.stopCmds,
|
||||
exitCommands=options.exitCmds)
|
||||
exitCommands=options.exitCmds,
|
||||
terminateCommands=options.terminateCmds)
|
||||
|
||||
if response['success']:
|
||||
if options.sourceBreakpoints:
|
||||
|
@ -1089,6 +1107,15 @@ def main():
|
|||
help=('Specify a LLDB command that will be executed when the process '
|
||||
'exits. Can be specified more than once.'))
|
||||
|
||||
parser.add_option(
|
||||
'--terminateCommand',
|
||||
type='string',
|
||||
action='append',
|
||||
dest='terminateCmds',
|
||||
default=[],
|
||||
help=('Specify a LLDB command that will be executed when the debugging '
|
||||
'session is terminated. Can be specified more than once.'))
|
||||
|
||||
parser.add_option(
|
||||
'--env',
|
||||
type='string',
|
||||
|
|
|
@ -43,7 +43,6 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
if continueToExit:
|
||||
self.continue_to_exit()
|
||||
|
||||
|
||||
@skipIfWindows
|
||||
@skipIfNetBSD # Hangs on NetBSD as well
|
||||
@skipIfRemote
|
||||
|
@ -121,8 +120,8 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
def test_commands(self):
|
||||
'''
|
||||
Tests the "initCommands", "preRunCommands", "stopCommands",
|
||||
"exitCommands", and "attachCommands" that can be passed during
|
||||
attach.
|
||||
"exitCommands", "terminateCommands" and "attachCommands"
|
||||
that can be passed during attach.
|
||||
|
||||
"initCommands" are a list of LLDB commands that get executed
|
||||
before the targt is created.
|
||||
|
@ -136,6 +135,8 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
must have a valid process in the selected target in LLDB after
|
||||
they are done executing. This allows custom commands to create any
|
||||
kind of debug session.
|
||||
"terminateCommands" are a list of LLDB commands that get executed when
|
||||
the debugger session terminates.
|
||||
'''
|
||||
self.build_and_create_debug_adaptor()
|
||||
program = self.getBuildArtifact("a.out")
|
||||
|
@ -150,13 +151,14 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
preRunCommands = ['image list a.out', 'image dump sections a.out']
|
||||
stopCommands = ['frame variable', 'bt']
|
||||
exitCommands = ['expr 2+3', 'expr 3+4']
|
||||
terminateCommands = ['expr 4+2']
|
||||
self.attach(program=program,
|
||||
attachCommands=attachCommands,
|
||||
initCommands=initCommands,
|
||||
preRunCommands=preRunCommands,
|
||||
stopCommands=stopCommands,
|
||||
exitCommands=exitCommands)
|
||||
|
||||
exitCommands=exitCommands,
|
||||
terminateCommands=terminateCommands)
|
||||
# Get output from the console. This should contain both the
|
||||
# "initCommands" and the "preRunCommands".
|
||||
output = self.get_console()
|
||||
|
@ -187,5 +189,35 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
self.continue_to_exit()
|
||||
# Get output from the console. This should contain both the
|
||||
# "exitCommands" that were run after the second breakpoint was hit
|
||||
output = self.get_console(timeout=1.0)
|
||||
# and the "terminateCommands" due to the debugging session ending
|
||||
output = self.collect_console(duration=1.0)
|
||||
self.verify_commands('exitCommands', output, exitCommands)
|
||||
self.verify_commands('terminateCommands', output, terminateCommands)
|
||||
|
||||
@skipIfWindows
|
||||
@skipIfNetBSD # Hangs on NetBSD as well
|
||||
def test_terminate_commands(self):
|
||||
'''
|
||||
Tests that the "terminateCommands", that can be passed during
|
||||
attach, are run when the debugger is disconnected.
|
||||
'''
|
||||
self.build_and_create_debug_adaptor()
|
||||
program = self.getBuildArtifact("a.out")
|
||||
# Here we just create a target and launch the process as a way to test
|
||||
# if we are able to use attach commands to create any kind of a target
|
||||
# and use it for debugging
|
||||
attachCommands = [
|
||||
'target create -d "%s"' % (program),
|
||||
'process launch'
|
||||
]
|
||||
terminateCommands = ['expr 4+2']
|
||||
self.attach(program=program,
|
||||
attachCommands=attachCommands,
|
||||
terminateCommands=terminateCommands,
|
||||
disconnectAutomatically=False)
|
||||
self.get_console()
|
||||
# Once it's disconnected the console should contain the
|
||||
# "terminateCommands"
|
||||
self.vscode.request_disconnect(terminateDebuggee=True)
|
||||
output = self.collect_console(duration=1.0)
|
||||
self.verify_commands('terminateCommands', output, terminateCommands)
|
||||
|
|
|
@ -294,8 +294,9 @@ class TestVSCode_launch(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
@skipIfRemote
|
||||
def test_commands(self):
|
||||
'''
|
||||
Tests the "initCommands", "preRunCommands", "stopCommands" and
|
||||
"exitCommands" that can be passed during launch.
|
||||
Tests the "initCommands", "preRunCommands", "stopCommands",
|
||||
"terminateCommands" and "exitCommands" that can be passed during
|
||||
launch.
|
||||
|
||||
"initCommands" are a list of LLDB commands that get executed
|
||||
before the targt is created.
|
||||
|
@ -305,17 +306,21 @@ class TestVSCode_launch(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
time the program stops.
|
||||
"exitCommands" are a list of LLDB commands that get executed when
|
||||
the process exits
|
||||
"terminateCommands" are a list of LLDB commands that get executed when
|
||||
the debugger session terminates.
|
||||
'''
|
||||
program = self.getBuildArtifact("a.out")
|
||||
initCommands = ['target list', 'platform list']
|
||||
preRunCommands = ['image list a.out', 'image dump sections a.out']
|
||||
stopCommands = ['frame variable', 'bt']
|
||||
exitCommands = ['expr 2+3', 'expr 3+4']
|
||||
terminateCommands = ['expr 4+2']
|
||||
self.build_and_launch(program,
|
||||
initCommands=initCommands,
|
||||
preRunCommands=preRunCommands,
|
||||
stopCommands=stopCommands,
|
||||
exitCommands=exitCommands)
|
||||
exitCommands=exitCommands,
|
||||
terminateCommands=terminateCommands)
|
||||
|
||||
# Get output from the console. This should contain both the
|
||||
# "initCommands" and the "preRunCommands".
|
||||
|
@ -354,8 +359,10 @@ class TestVSCode_launch(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
self.continue_to_exit()
|
||||
# Get output from the console. This should contain both the
|
||||
# "exitCommands" that were run after the second breakpoint was hit
|
||||
output = self.get_console(timeout=1.0)
|
||||
# and the "terminateCommands" due to the debugging session ending
|
||||
output = self.collect_console(duration=1.0)
|
||||
self.verify_commands('exitCommands', output, exitCommands)
|
||||
self.verify_commands('terminateCommands', output, terminateCommands)
|
||||
|
||||
@skipIfWindows
|
||||
@skipIfRemote
|
||||
|
@ -420,3 +427,23 @@ class TestVSCode_launch(lldbvscode_testcase.VSCodeTestCaseBase):
|
|||
# "exitCommands" that were run after the second breakpoint was hit
|
||||
output = self.get_console(timeout=1.0)
|
||||
self.verify_commands('exitCommands', output, exitCommands)
|
||||
|
||||
@skipIfWindows
|
||||
@skipIfNetBSD # Hangs on NetBSD as well
|
||||
def test_terminate_commands(self):
|
||||
'''
|
||||
Tests that the "terminateCommands", that can be passed during
|
||||
launch, are run when the debugger is disconnected.
|
||||
'''
|
||||
self.build_and_create_debug_adaptor()
|
||||
program = self.getBuildArtifact("a.out")
|
||||
|
||||
terminateCommands = ['expr 4+2']
|
||||
self.launch(program=program,
|
||||
terminateCommands=terminateCommands)
|
||||
self.get_console()
|
||||
# Once it's disconnected the console should contain the
|
||||
# "terminateCommands"
|
||||
self.vscode.request_disconnect(terminateDebuggee=True)
|
||||
output = self.collect_console(duration=1.0)
|
||||
self.verify_commands('terminateCommands', output, terminateCommands)
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
|
||||
The `lldb-vscode` tool creates a command line tool that implements the [Visual
|
||||
Studio Code Debug API](https://code.visualstudio.com/docs/extensionAPI/api-debugging).
|
||||
It can be installed as an extension for the Visual Studio Code and Nuclide IDE.
|
||||
It can be installed as an extension for the Visual Studio Code and Nuclide IDE.
|
||||
The protocol is easy to run remotely and also can allow other tools and IDEs to
|
||||
get a full featured debugger with a well defined protocol.
|
||||
get a full featured debugger with a well defined protocol.
|
||||
|
||||
# Installation for Visual Studio Code
|
||||
|
||||
Installing the plug-in involves creating a directory in the `~/.vscode/extensions` folder and copying the package.json file that is in the same directory as this
|
||||
documentation into it, and copying to symlinking a lldb-vscode binary into
|
||||
documentation into it, and copying to symlinking a lldb-vscode binary into
|
||||
the `bin` directory inside the plug-in directory.
|
||||
|
||||
If you want to make a stand alone plug-in that you can send to others on unix systems:
|
||||
|
@ -86,6 +86,7 @@ file that defines how your program will be run. The JSON configuration file can
|
|||
|**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**stopCommands** |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**exitCommands** |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**sourceMap** |[string[2]]| | Specify an array of path re-mappings. Each element in the array must be a two element array containing a source and destination pathname.
|
||||
|**debuggerRoot** | string| |Specify a working directory to use when launching lldb-vscode. If the debug information in your executable contains relative paths, this option can be used so that `lldb-vscode` can find source files and object files that have relative paths.
|
||||
|
||||
|
@ -112,6 +113,7 @@ The JSON configuration file can contain the following `lldb-vscode` specific lau
|
|||
|**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**stopCommands** |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**exitCommands** |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed.
|
||||
|**attachCommands** |[string]| | LLDB commands that will be executed after **preRunCommands** which take place of the code that normally does the attach. The commands can create a new target and attach or launch it however desired. This allows custom launch and attach configurations. Core files can use `target create --core /path/to/core` to attach to core files.
|
||||
|
||||
|
||||
|
|
|
@ -309,6 +309,10 @@ void VSCode::RunExitCommands() {
|
|||
RunLLDBCommands("Running exitCommands:", exit_commands);
|
||||
}
|
||||
|
||||
void VSCode::RunTerminateCommands() {
|
||||
RunLLDBCommands("Running terminateCommands:", terminate_commands);
|
||||
}
|
||||
|
||||
lldb::SBTarget VSCode::CreateTargetFromArguments(
|
||||
const llvm::json::Object &arguments,
|
||||
lldb::SBError &error) {
|
||||
|
|
|
@ -86,6 +86,7 @@ struct VSCode {
|
|||
std::vector<std::string> pre_run_commands;
|
||||
std::vector<std::string> exit_commands;
|
||||
std::vector<std::string> stop_commands;
|
||||
std::vector<std::string> terminate_commands;
|
||||
lldb::tid_t focus_tid;
|
||||
bool sent_terminated_event;
|
||||
bool stop_at_entry;
|
||||
|
@ -133,6 +134,7 @@ struct VSCode {
|
|||
void RunPreRunCommands();
|
||||
void RunStopCommands();
|
||||
void RunExitCommands();
|
||||
void RunTerminateCommands();
|
||||
|
||||
/// Create a new SBTarget object from the given request arguments.
|
||||
/// \param[in] arguments
|
||||
|
|
|
@ -174,6 +174,7 @@ void SendThreadExitedEvent(lldb::tid_t tid) {
|
|||
void SendTerminatedEvent() {
|
||||
if (!g_vsc.sent_terminated_event) {
|
||||
g_vsc.sent_terminated_event = true;
|
||||
g_vsc.RunTerminateCommands();
|
||||
// Send a "terminated" event
|
||||
llvm::json::Object event(CreateEventObject("terminated"));
|
||||
g_vsc.SendJSON(llvm::json::Value(std::move(event)));
|
||||
|
@ -530,6 +531,7 @@ void request_attach(const llvm::json::Object &request) {
|
|||
g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
|
||||
g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
|
||||
g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
|
||||
g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands");
|
||||
auto attachCommands = GetStrings(arguments, "attachCommands");
|
||||
llvm::StringRef core_file = GetString(arguments, "coreFile");
|
||||
g_vsc.stop_at_entry =
|
||||
|
@ -775,7 +777,6 @@ void request_disconnect(const llvm::json::Object &request) {
|
|||
GetBoolean(arguments, "terminateDebuggee", defaultTerminateDebuggee);
|
||||
lldb::SBProcess process = g_vsc.target.GetProcess();
|
||||
auto state = process.GetState();
|
||||
|
||||
switch (state) {
|
||||
case lldb::eStateInvalid:
|
||||
case lldb::eStateUnloaded:
|
||||
|
@ -797,8 +798,8 @@ void request_disconnect(const llvm::json::Object &request) {
|
|||
g_vsc.debugger.SetAsync(true);
|
||||
break;
|
||||
}
|
||||
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
|
||||
SendTerminatedEvent();
|
||||
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
|
||||
if (g_vsc.event_thread.joinable()) {
|
||||
g_vsc.broadcaster.BroadcastEventByType(eBroadcastBitStopEventThread);
|
||||
g_vsc.event_thread.join();
|
||||
|
@ -1368,6 +1369,7 @@ void request_launch(const llvm::json::Object &request) {
|
|||
g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
|
||||
g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
|
||||
g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
|
||||
g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands");
|
||||
auto launchCommands = GetStrings(arguments, "launchCommands");
|
||||
g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
|
||||
const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
|
||||
|
|
Loading…
Reference in New Issue