diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/TestVSCode_completions.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/TestVSCode_completions.py --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/TestVSCode_completions.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/TestVSCode_completions.py @@ -113,3 +113,76 @@ } ], ) + + self.verify_completions( + self.vscode.get_completions("foo1.v"), + [ + { + "text": "var1", + "label": "foo1.var1 -- int" + } + ] + ) + + self.verify_completions( + self.vscode.get_completions("foo1.my_bar_object.v"), + [ + { + "text": "var1", + "label": "foo1.my_bar_object.var1 -- int" + } + ] + ) + + self.verify_completions( + self.vscode.get_completions("foo1.var1 + foo1.v"), + [ + { + "text": "var1", + "label": "foo1.var1 -- int" + } + ] + ) + + self.verify_completions( + self.vscode.get_completions("foo1.var1 + v"), + [ + { + "text": "var1", + "label": "var1 -- int &" + } + ] + ) + + #should correctly handle spaces between objects and member operators + self.verify_completions( + self.vscode.get_completions("foo1 .v"), + [ + { + "text": "var1", + "label": ".var1 -- int" + } + ], + [ + { + "text": "var2", + "label": ".var2 -- int" + } + ] + ) + + self.verify_completions( + self.vscode.get_completions("foo1 . v"), + [ + { + "text": "var1", + "label": "var1 -- int" + } + ], + [ + { + "text": "var2", + "label": "var2 -- int" + } + ] + ) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/main.cpp b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/main.cpp --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/main.cpp +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/completions/main.cpp @@ -1,6 +1,17 @@ #include #include +struct bar { + int var1; +}; + +struct foo { + int var1; + bar* my_bar_pointer; + bar my_bar_object; + foo* next_foo; +}; + int fun(std::vector var) { return var.size(); // breakpoint 1 } @@ -12,5 +23,8 @@ std::string str2 = "b"; std::vector vec; fun(vec); + bar bar1 = {2}; + bar* bar2 = &bar1; + foo foo1 = {3,&bar1, bar1, NULL}; return 0; // breakpoint 2 } diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/Makefile b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/Makefile new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/TestVSCode_environmentVariables.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/TestVSCode_environmentVariables.py new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/TestVSCode_environmentVariables.py @@ -0,0 +1,36 @@ +""" +Test lldb-vscode completions request +""" + + +import lldbvscode_testcase +import unittest2 +import vscode +from lldbsuite.test import lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import os + + +class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfWindows + #@skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots + def test_environment_variable(self): + """ + Tests the completion request at different breakpoints + """ + program = self.getBuildArtifact("a.out") + path_env_variable = 'PATH='+os.environ['PATH'] + self.build_and_launch(program, inheritEnvironment=False) + self.continue_to_exit() + output = self.get_stdout().encode('utf-8') + lines = output.splitlines() + found = False + for line in lines: + if line.startswith('PATH='): + found = True + self.assertTrue(path_env_variable == line, "PATH environment variable not the same") + self.assertTrue(found, 'PATH environment variable not found') \ No newline at end of file diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/main.cpp b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/main.cpp new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/environmentVariables/main.cpp @@ -0,0 +1,17 @@ +#include +#include +#include +#include + +extern char **environ; + +int main(int argc, char const *argv[], char const *envp[]) { + char** env_var_pointer = environ; + // std::vector vscode_env_variables; + int count = 0; + for (char* env_variable = *env_var_pointer; env_variable; env_variable=*++env_var_pointer) { + printf("%s\n", env_variable); + count++; + } + return 0; // breakpoint 1 +} diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py @@ -265,7 +265,7 @@ disableSTDIO=False, shellExpandArguments=False, trace=False, initCommands=None, preRunCommands=None, stopCommands=None, exitCommands=None,sourcePath= None, - debuggerRoot=None, launchCommands=None): + debuggerRoot=None, launchCommands=None, inheritEnvironment=False): '''Sending launch request to vscode ''' @@ -296,7 +296,9 @@ exitCommands=exitCommands, sourcePath=sourcePath, debuggerRoot=debuggerRoot, - launchCommands=launchCommands) + launchCommands=launchCommands, + inheritEnvironment=inheritEnvironment + ) if not (response and response['success']): self.assertTrue(response['success'], 'launch failed (%s)' % (response['message'])) @@ -306,14 +308,13 @@ disableSTDIO=False, shellExpandArguments=False, trace=False, initCommands=None, preRunCommands=None, stopCommands=None, exitCommands=None, - sourcePath=None, debuggerRoot=None): + sourcePath=None, debuggerRoot=None, inheritEnvironment=False): '''Build the default Makefile target, create the VSCode debug adaptor, and launch the process. ''' self.build_and_create_debug_adaptor() self.assertTrue(os.path.exists(program), 'executable must exist') - self.launch(program, args, cwd, env, stopOnEntry, disableASLR, disableSTDIO, shellExpandArguments, trace, initCommands, preRunCommands, stopCommands, exitCommands, - sourcePath, debuggerRoot) + sourcePath, debuggerRoot, inheritEnvironment=inheritEnvironment) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py @@ -562,7 +562,7 @@ disableSTDIO=False, shellExpandArguments=False, trace=False, initCommands=None, preRunCommands=None, stopCommands=None, exitCommands=None, sourcePath=None, - debuggerRoot=None, launchCommands=None): + debuggerRoot=None, launchCommands=None, inheritEnvironment=False): args_dict = { 'program': program } @@ -597,6 +597,8 @@ args_dict['debuggerRoot'] = debuggerRoot if launchCommands: args_dict['launchCommands'] = launchCommands + if inheritEnvironment: + args_dict['inheritEnvironment'] = inheritEnvironment command_dict = { 'command': 'launch', 'type': 'request', @@ -900,7 +902,9 @@ initCommands=options.initCmds, preRunCommands=options.preRunCmds, stopCommands=options.stopCmds, - exitCommands=options.exitCmds) + exitCommands=options.exitCmds + inheritEnvironment=options.inheritEnvironment + ) if response['success']: if options.sourceBreakpoints: diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp --- a/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -49,6 +49,8 @@ #include "LLDBUtils.h" #include "VSCode.h" +extern char **environ; + #if defined(_WIN32) #ifndef PATH_MAX #define PATH_MAX MAX_PATH @@ -951,9 +953,17 @@ for (size_t i = 0; i < count; i++) { std::string match = matches.GetStringAtIndex(i); std::string description = descriptions.GetStringAtIndex(i); - + llvm::json::Object item; - EmplaceSafeString(item, "text", match); + + llvm::StringRef match_ref = match; + for(llvm::StringRef commit_point: {".", "->"}) { + if (match_ref.contains(commit_point)){ + match_ref = match_ref.rsplit(commit_point).second; + } + } + EmplaceSafeString(item, "text", match_ref); + if (description.empty()) EmplaceSafeString(item, "label", match); else @@ -1332,6 +1342,7 @@ auto launchCommands = GetStrings(arguments, "launchCommands"); g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false); const auto debuggerRoot = GetString(arguments, "debuggerRoot"); + bool launchWithDebuggerEnvironment = GetBoolean(arguments, "inheritEnvironment", false); // This is a hack for loading DWARF in .o files on Mac where the .o files // in the debug map of the main executable have relative paths which require @@ -1379,13 +1390,24 @@ // Extract any extra arguments and append them to our program arguments for // when we launch auto args = GetStrings(arguments, "args"); - if (!args.empty()) + if (!args.empty()) g_vsc.launch_info.SetArguments(MakeArgv(args).data(), true); // Pass any environment variables along that the user specified. auto envs = GetStrings(arguments, "env"); - if (!envs.empty()) + + if (launchWithDebuggerEnvironment) { + char** env_var_pointer = environ; + std::vector vscode_env_variables; + for (char* env_variable = *env_var_pointer; env_variable; env_variable=*++env_var_pointer){ + vscode_env_variables.push_back(env_variable); + } + envs.insert(std::end(envs), std::begin(vscode_env_variables), std::end(vscode_env_variables)); + } + + if (!envs.empty()) { g_vsc.launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true); + } auto flags = g_vsc.launch_info.GetLaunchFlags(); diff --git a/lldb/tools/lldb-vscode/package.json b/lldb/tools/lldb-vscode/package.json --- a/lldb/tools/lldb-vscode/package.json +++ b/lldb/tools/lldb-vscode/package.json @@ -84,6 +84,11 @@ "description": "Additional environment variables.", "default": [] }, + "inheritEnvironment": { + "type": "boolean", + "description": "Inherit the VSCode Environment Variables", + "default": false + }, "stopOnEntry": { "type": "boolean", "description": "Automatically stop after launch.",