Index: packages/Python/lldbsuite/test/functionalities/var_path/Makefile =================================================================== --- packages/Python/lldbsuite/test/functionalities/var_path/Makefile +++ packages/Python/lldbsuite/test/functionalities/var_path/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/functionalities/var_path/TestVarPath.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/var_path/TestVarPath.py +++ packages/Python/lldbsuite/test/functionalities/var_path/TestVarPath.py @@ -0,0 +1,103 @@ +""" +Make sure the getting a variable path works and doesn't crash. +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestVarPath(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # If your test case doesn't stress debug info, the + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + def test_frame_var(self): + self.build() + self.do_test() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def verify_point(self, frame, var_name, var_typename, x_value, y_value): + v = frame.GetValueForVariablePath(var_name) + self.assertTrue(v.GetError().Success(), "Make sure we find '%s'" % (var_name)) + self.assertTrue(v.GetType().GetName() == var_typename, + "Make sure '%s' has type '%s'" % (var_name, var_typename)) + + if '*' in var_typename: + valid_prefix = var_name + '->' + invalid_prefix = var_name + '.' + else: + valid_prefix = var_name + '.' + invalid_prefix = var_name + '->' + + valid_x_path = valid_prefix + 'x' + valid_y_path = valid_prefix + 'y' + invalid_x_path = invalid_prefix + 'x' + invalid_y_path = invalid_prefix + 'y' + invalid_m_path = invalid_prefix + 'm' + + v = frame.GetValueForVariablePath(valid_x_path) + self.assertTrue(v.GetError().Success(), "Make sure we find '%s'" % (valid_x_path)) + self.assertTrue(v.GetValue() == str(x_value), "Make sure '%s' has a value of %i" % (valid_x_path, x_value)) + self.assertTrue(v.GetType().GetName() == "int", "Make sure '%s' has type 'int'" % (valid_x_path)) + v = frame.GetValueForVariablePath(invalid_x_path) + self.assertTrue(v.GetError().Fail(), "Make sure we don't find '%s'" % (invalid_x_path)) + + v = frame.GetValueForVariablePath(valid_y_path) + self.assertTrue(v.GetError().Success(), "Make sure we find '%s'" % (valid_y_path)) + self.assertTrue(v.GetValue() == str(y_value), "Make sure '%s' has a value of %i" % (valid_y_path, y_value)) + self.assertTrue(v.GetType().GetName() == "int", "Make sure '%s' has type 'int'" % (valid_y_path)) + v = frame.GetValueForVariablePath(invalid_y_path) + self.assertTrue(v.GetError().Fail(), "Make sure we don't find '%s'" % (invalid_y_path)) + + v = frame.GetValueForVariablePath(invalid_m_path) + self.assertTrue(v.GetError().Fail(), "Make sure we don't find '%s'" % (invalid_m_path)) + + def do_test(self): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "// Set a breakpoint here", lldb.SBFileSpec("main.cpp")) + + frame = thread.GetFrameAtIndex(0) + v = frame.GetValueForVariablePath('no_such_variable') + self.assertTrue(v.GetError().Fail(), "Make sure we don't find 'no_such_variable'") + + # Test an instance + self.verify_point(frame, 'pt', 'Point', 1, 2) + # Test a pointer + self.verify_point(frame, 'pt_ptr', 'Point *', 3030, 4040) + # Test using a pointer as an array + self.verify_point(frame, 'pt_ptr[-1]', 'Point', 1010, 2020) + self.verify_point(frame, 'pt_ptr[0]', 'Point', 3030, 4040) + self.verify_point(frame, 'pt_ptr[1]', 'Point', 5050, 6060) + # Test arrays + v = frame.GetValueForVariablePath('points') + self.assertTrue(v.GetError().Success(), + "Make sure we find 'points'") + self.verify_point(frame, 'points[0]', 'Point', 1010, 2020) + self.verify_point(frame, 'points[1]', 'Point', 3030, 4040) + self.verify_point(frame, 'points[2]', 'Point', 5050, 6060) + # Test a reference + self.verify_point(frame, 'pt_ref', 'Point &', 1, 2) + v = frame.GetValueForVariablePath('pt_sp') + self.assertTrue(v.GetError().Success(), "Make sure we find 'pt_sp'") + # Make sure we don't crash when looking for non existant child + # in type with synthetic children. This used to cause a crash. + v = frame.GetValueForVariablePath('pt_sp->not_valid_child') + self.assertTrue(v.GetError().Fail(), + "Make sure we don't find 'pt_sp->not_valid_child'") + + + Index: packages/Python/lldbsuite/test/functionalities/var_path/main.cpp =================================================================== --- packages/Python/lldbsuite/test/functionalities/var_path/main.cpp +++ packages/Python/lldbsuite/test/functionalities/var_path/main.cpp @@ -0,0 +1,15 @@ +#include + +struct Point { + int x, y; +}; + +int main() { + Point pt = { 1, 2 }; + Point points[] = {{1010,2020}, {3030,4040}, {5050,6060}}; + Point *pt_ptr = &points[1]; + Point &pt_ref = pt; + std::shared_ptr pt_sp(new Point{111,222}); + return 0; // Set a breakpoint here +} + Index: source/Target/StackFrame.cpp =================================================================== --- source/Target/StackFrame.cpp +++ source/Target/StackFrame.cpp @@ -642,7 +642,12 @@ valobj_sp = valobj_sp->Dereference(deref_error); if (error.Fail()) { error.SetErrorStringWithFormatv( - "Failed to dereference sythetic value: %s", deref_error); + "Failed to dereference sythetic value: {0}", deref_error); + return ValueObjectSP(); + } + // Some synthetic plug-ins fail to set the error in Dereference + if (!valobj_sp) { + error.SetErrorString("Failed to dereference sythetic value"); return ValueObjectSP(); } expr_is_ptr = false;