aboutsummaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py53
-rw-r--r--lldb/tools/lldb-vscode/lldb-vscode.cpp25
2 files changed, 77 insertions, 1 deletions
diff --git a/lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py b/lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
index e4cb103..9b91955 100644
--- a/lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
+++ b/lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
@@ -7,7 +7,7 @@ from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import lldbvscode_testcase
-
+import os
def make_buffer_verify_dict(start_idx, count, offset=0):
verify_dict = {}
@@ -38,6 +38,14 @@ class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase):
' "%s")') % (
key, actual_value,
verify_value))
+ if 'contains' in verify_dict:
+ verify = verify_dict['contains']
+ for key in verify:
+ contains_array = verify[key]
+ actual_value = actual[key]
+ self.assertTrue(isinstance(contains_array, list))
+ for verify_value in contains_array:
+ self.assertIn(verify_value, actual_value)
if 'missing' in verify_dict:
missing = verify_dict['missing']
for key in missing:
@@ -508,3 +516,46 @@ class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase):
self.assertTrue(value.startswith('0x'))
self.assertTrue('a.out`main + ' in value)
self.assertTrue('at main.cpp:' in value)
+
+ @no_debug_info_test
+ @skipUnlessDarwin
+ def test_darwin_dwarf_missing_obj(self):
+ '''
+ Test that if we build a binary with DWARF in .o files and we remove
+ the .o file for main.cpp, that we get a variable named "<error>"
+ whose value matches the appriopriate error. Errors when getting
+ variables are returned in the LLDB API when the user should be
+ notified of issues that can easily be solved by rebuilding or
+ changing compiler options and are designed to give better feedback
+ to the user.
+ '''
+ self.build(debug_info="dwarf")
+ program = self.getBuildArtifact("a.out")
+ main_obj = self.getBuildArtifact("main.o")
+ self.assertTrue(os.path.exists(main_obj))
+ # Delete the main.o file that contains the debug info so we force an
+ # error when we run to main and try to get variables
+ os.unlink(main_obj)
+
+ self.create_debug_adaptor()
+ self.assertTrue(os.path.exists(program), 'executable must exist')
+ self.launch(program)
+
+ functions = ['main']
+ breakpoint_ids = self.set_function_breakpoints(functions)
+ self.assertEquals(len(breakpoint_ids), len(functions), "expect one breakpoint")
+ self.continue_to_breakpoints(breakpoint_ids)
+
+ locals = self.vscode.get_local_variables()
+
+ verify_locals = {
+ '<error>': {
+ 'equals': {'type': 'const char *'},
+ 'contains': { 'value': [
+ 'debug map object file ',
+ 'main.o" containing debug info does not exist, debug info will not be loaded']
+ }
+ },
+ }
+ varref_dict = {}
+ self.verify_variables(verify_locals, locals, varref_dict)
diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp
index 22ff84f..b728591 100644
--- a/lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -2953,6 +2953,31 @@ void request_variables(const llvm::json::Object &request) {
}
num_children = top_scope->GetSize();
+ if (num_children == 0 && variablesReference == VARREF_LOCALS) {
+ // Check for an error in the SBValueList that might explain why we don't
+ // have locals. If we have an error display it as the sole value in the
+ // the locals.
+
+ // "error" owns the error string so we must keep it alive as long as we
+ // want to use the returns "const char *"
+ lldb::SBError error = top_scope->GetError();
+ const char *var_err = error.GetCString();
+ if (var_err) {
+ // Create a fake variable named "error" to explain why variables were
+ // not available. This new error will help let users know when there was
+ // a problem that kept variables from being available for display and
+ // allow users to fix this issue instead of seeing no variables. The
+ // errors are only set when there is a problem that the user could
+ // fix, so no error will show up when you have no debug info, only when
+ // we do have debug info and something that is fixable can be done.
+ llvm::json::Object object;
+ EmplaceSafeString(object, "name", "<error>");
+ EmplaceSafeString(object, "type", "const char *");
+ EmplaceSafeString(object, "value", var_err);
+ object.try_emplace("variablesReference", (int64_t)0);
+ variables.emplace_back(std::move(object));
+ }
+ }
const int64_t end_idx = start_idx + ((count == 0) ? num_children : count);
// We first find out which variable names are duplicated