--- /dev/null
+"""
+Test lldb-vscode setBreakpoints request
+"""
+
+from __future__ import print_function
+
+import unittest2
+import vscode
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbvscode_testcase
+
+
+class TestVSCode_console(lldbvscode_testcase.VSCodeTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def check_lldb_command(self, lldb_command, contains_string, assert_msg):
+ response = self.vscode.request_evaluate('`%s' % (lldb_command))
+ output = response['body']['result']
+ self.assertTrue(contains_string in output,
+ ("""Verify %s by checking the command output:\n"""
+ """'''\n%s'''\nfor the string: "%s" """ % (
+ assert_msg, output, contains_string)))
+
+ @skipIfWindows
+ @skipIfRemote
+ def test_scopes_variables_setVariable_evaluate(self):
+ '''
+ Tests that the "scopes" request causes the currently selected
+ thread and frame to be updated. There are no DAP packets that tell
+ lldb-vscode which thread and frame are selected other than the
+ "scopes" request. lldb-vscode will now select the thread and frame
+ for the latest "scopes" request that it receives.
+
+ The LLDB command interpreter needs to have the right thread and
+ frame selected so that commands executed in the debug console act
+ on the right scope. This applies both to the expressions that are
+ evaluated and the lldb commands that start with the backtick
+ character.
+ '''
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ source = 'main.cpp'
+ breakpoint1_line = line_number(source, '// breakpoint 1')
+ lines = [breakpoint1_line]
+ # Set breakpoint in the thread function so we can step the threads
+ breakpoint_ids = self.set_source_breakpoints(source, lines)
+ self.assertTrue(len(breakpoint_ids) == len(lines),
+ "expect correct number of breakpoints")
+ self.continue_to_breakpoints(breakpoint_ids)
+ # Cause a "scopes" to be sent for frame zero which should update the
+ # selected thread and frame to frame 0.
+ self.vscode.get_local_variables(frameIndex=0)
+ # Verify frame #0 is selected in the command interpreter by running
+ # the "frame select" command with no frame index which will print the
+ # currently selected frame.
+ self.check_lldb_command("frame select", "frame #0",
+ "frame 0 is selected")
+
+ # Cause a "scopes" to be sent for frame one which should update the
+ # selected thread and frame to frame 1.
+ self.vscode.get_local_variables(frameIndex=1)
+ # Verify frame #1 is selected in the command interpreter by running
+ # the "frame select" command with no frame index which will print the
+ # currently selected frame.
+
+ self.check_lldb_command("frame select", "frame #1",
+ "frame 1 is selected")
for (size_t i = 0; i < count; i++) {
std::string match = matches.GetStringAtIndex(i);
std::string description = descriptions.GetStringAtIndex(i);
-
+
llvm::json::Object item;
llvm::StringRef match_ref = match;
// The debug adapter supports the stepInTargetsRequest.
body.try_emplace("supportsStepInTargetsRequest", false);
// We need to improve the current implementation of completions in order to
- // enable it again. For some context, this is how VSCode works:
+ // enable it again. For some context, this is how VSCode works:
// - VSCode sends a completion request whenever chars are added, the user
// triggers completion manually via CTRL-space or similar mechanisms, but
// not when there's a deletion. Besides, VSCode doesn't let us know which
llvm::json::Object body;
auto arguments = request.getObject("arguments");
lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+ // As the user selects different stack frames in the GUI, a "scopes" request
+ // will be sent to the DAP. This is the only way we know that the user has
+ // selected a frame in a thread. There are no other notifications that are
+ // sent and VS code doesn't allow multiple frames to show variables
+ // concurrently. If we select the thread and frame as the "scopes" requests
+ // are sent, this allows users to type commands in the debugger console
+ // with a backtick character to run lldb commands and these lldb commands
+ // will now have the right context selected as they are run. If the user
+ // types "`bt" into the debugger console and we had another thread selected
+ // in the LLDB library, we would show the wrong thing to the user. If the
+ // users switches threads with a lldb command like "`thread select 14", the
+ // GUI will not update as there are no "event" notification packets that
+ // allow us to change the currently selected thread or frame in the GUI that
+ // I am aware of.
+ if (frame.IsValid()) {
+ frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+ frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+ }
g_vsc.variables.Clear();
g_vsc.variables.Append(frame.GetVariables(true, // arguments
true, // locals