def break_commands(self): """Tests that we can set a conditional breakpoint in Swift code""" (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "Set breakpoint here", lldb.SBFileSpec("main.swift")) bkpt.SetCondition("x==y") threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit conditional breakpoint - first time") self.check_x_and_y(threads[0].frames[0], '5', '5') threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit conditional breakpoint - second time") self.check_x_and_y(threads[0].frames[0], '6', '6') bkpt.SetCondition('x>y') threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit conditional breakpoint - third time") self.check_x_and_y(threads[0].frames[0], '3', '1')
def test_break_in_dlopen_dylib_using_target(self): self.common_setup() target, process, _, _ = lldbutil.run_to_source_breakpoint( self, "Break here before we dlopen", self.main_spec, extra_images=[self.lib_shortname]) # Now set some breakpoints that won't take till the library is loaded: # This one is currently how lldbutils does it but test here in case that changes: bkpt1 = target.BreakpointCreateBySourceRegex("Break here in dylib", self.b_spec, self.lib_fullname) # Try the file list API as well. Put in some bogus entries too, to make sure those # don't trip us up: files_list = lldb.SBFileSpecList() files_list.Append(self.b_spec) files_list.Append(self.main_spec) files_list.Append(lldb.SBFileSpec("I_bet_nobody_has_this_file.cpp")) modules_list = lldb.SBFileSpecList() modules_list.Append(self.lib_spec) modules_list.Append( lldb.SBFileSpec("libI_bet_not_this_one_either.dylib")) bkpt2 = target.BreakpointCreateBySourceRegex("Break here in dylib", modules_list, files_list) lldbutil.continue_to_breakpoint(process, bkpt1) self.assertEqual(bkpt1.GetHitCount(), 1, "Hit breakpoint 1") self.assertEqual(bkpt2.GetHitCount(), 1, "Hit breakpoint 2")
def do_test_ptr_and_ref(self, stdlib_type): """Test that ref and ptr to std::list is displayed correctly""" self.build(dictionary={stdlib_type: "1"}) (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint( self, 'Check ref and ptr', lldb.SBFileSpec("main.cpp", False)) self.expect("frame variable ref", substrs=[ 'size=4', '[0] = ', '1', '[1] = ', '2', '[2] = ', '3', '[3] = ', '4' ]) self.expect("frame variable *ptr", substrs=[ 'size=4', '[0] = ', '1', '[1] = ', '2', '[2] = ', '3', '[3] = ', '4' ]) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable ref", substrs=[ 'size=4', '[0]', 'goofy', '[1]', 'is', '[2]', 'smart', '[3]', '!!!' ]) self.expect("frame variable *ptr", substrs=[ 'size=4', '[0]', 'goofy', '[1]', 'is', '[2]', 'smart', '[3]', '!!!' ])
def sample_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Break here to get started", self.main_source_file) # Set breakpoints in the two class methods and run to them: namesp_bkpt = target.BreakpointCreateBySourceRegex("namesp function did something.", self.main_source_file) self.assertEqual(namesp_bkpt.GetNumLocations(), 1, "Namespace breakpoint invalid") virtual_bkpt = target.BreakpointCreateBySourceRegex("Virtual function did something.", self.main_source_file) self.assertEqual(virtual_bkpt.GetNumLocations(), 1, "Virtual breakpoint invalid") threads = lldbutil.continue_to_breakpoint(process, namesp_bkpt) self.assertEqual(len(threads), 1, "Didn't stop at namespace breakpoint") frame = threads[0].frame[0] namesp_this = frame.FindVariable("this", lldb.eDynamicCanRunTarget) # Clang specifies the type of this as "T *", gcc as "T * const". This # erases the difference. namesp_type = namesp_this.GetType().GetUnqualifiedType() self.assertEqual(namesp_type.GetName(), "namesp::Virtual *", "Didn't get the right dynamic type") threads = lldbutil.continue_to_breakpoint(process, virtual_bkpt) self.assertEqual(len(threads), 1, "Didn't stop at virtual breakpoint") frame = threads[0].frame[0] virtual_this = frame.FindVariable("this", lldb.eDynamicCanRunTarget) virtual_type = virtual_this.GetType().GetUnqualifiedType() self.assertEqual(virtual_type.GetName(), "Virtual *", "Didn't get the right dynamic type")
def sample_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "Break here to get started", self.main_source_file) # Set breakpoints in the two class methods and run to them: namesp_bkpt = target.BreakpointCreateBySourceRegex( "namesp function did something.", self.main_source_file) self.assertEqual(namesp_bkpt.GetNumLocations(), 1, "Namespace breakpoint invalid") virtual_bkpt = target.BreakpointCreateBySourceRegex( "Virtual function did something.", self.main_source_file) self.assertEqual(virtual_bkpt.GetNumLocations(), 1, "Virtual breakpoint invalid") threads = lldbutil.continue_to_breakpoint(process, namesp_bkpt) self.assertEqual(len(threads), 1, "Didn't stop at namespace breakpoint") frame = threads[0].frame[0] namesp_this = frame.FindVariable("this", lldb.eDynamicCanRunTarget) # Clang specifies the type of this as "T *", gcc as "T * const". This # erases the difference. namesp_type = namesp_this.GetType().GetUnqualifiedType() self.assertEqual(namesp_type.GetName(), "namesp::Virtual *", "Didn't get the right dynamic type") threads = lldbutil.continue_to_breakpoint(process, virtual_bkpt) self.assertEqual(len(threads), 1, "Didn't stop at virtual breakpoint") frame = threads[0].frame[0] virtual_this = frame.FindVariable("this", lldb.eDynamicCanRunTarget) virtual_type = virtual_this.GetType().GetUnqualifiedType() self.assertEqual(virtual_type.GetName(), "Virtual *", "Didn't get the right dynamic type")
def test_breakpoints_on_initializers(self): """Show we can set breakpoints on initializers appearing both before and after the constructor body, and hit them.""" self.build() self.main_source_file = lldb.SBFileSpec("main.cpp") self.first_initializer_line = line_number( "main.cpp", "Set the before constructor breakpoint here") self.second_initializer_line = line_number( "main.cpp", "Set the after constructor breakpoint here") (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, " Set a breakpoint here to get started", self.main_source_file) # Now set breakpoints on the two initializer lines we found in the test startup: bkpt1 = target.BreakpointCreateByLocation(self.main_source_file, self.first_initializer_line) self.assertEqual(bkpt1.GetNumLocations(), 1) bkpt2 = target.BreakpointCreateByLocation(self.main_source_file, self.second_initializer_line) self.assertEqual(bkpt2.GetNumLocations(), 1) # Now continue, we should stop at the two breakpoints above, first the one before, then # the one after. self.assertEqual(len(lldbutil.continue_to_breakpoint(process, bkpt1)), 1, "Hit first breakpoint") self.assertEqual(len(lldbutil.continue_to_breakpoint(process, bkpt2)), 1, "Hit second breakpoint")
def test_swift_deployment_target_dlopen(self): self.build() target, process, _, _, = lldbutil.run_to_name_breakpoint( self, 'main', exe_name="dlopen_module") bkpt = target.BreakpointCreateBySourceRegex( 'break here', lldb.SBFileSpec('NewerTarget.swift')) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("p self", substrs=['i = 23'])
def do_test_with_run_command(self, stdlib_type): """Test that that file and class static variables display correctly.""" # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.addTearDownHook(cleanup) self.build(dictionary={stdlib_type: "1"}) self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp(self, "break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) self.runCmd("frame variable has_optional") output = self.res.GetOutput() ## The variable has_optional tells us if the test program ## detected we have a sufficient libc++ version to support optional ## false means we do not and therefore should skip the test if output.find("(bool) has_optional = false") != -1: self.skipTest("Optional not supported") lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable number_not_engaged", substrs=['Has Value=false']) self.expect("frame variable number_engaged", substrs=['Has Value=true', 'Value = 42', '}']) self.expect("frame var numbers", substrs=[ '(optional_int_vect) numbers = Has Value=true {', 'Value = size=4 {', '[0] = 1', '[1] = 2', '[2] = 3', '[3] = 4', '}', '}' ]) self.expect("frame var ostring", substrs=[ '(optional_string) ostring = Has Value=true {', 'Value = "hello"', '}' ])
def test(self): """Test 'image lookup -t days' and check for correct display and enum value printing.""" self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. bkpt_id = lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs = [' resolved, hit count = 1']) # Look up information about the 'days' enum type. # Check for correct display. self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['enum days {', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '}']) enum_values = [ '-4', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '5']; # Make sure a pointer to an anonymous enum type does crash LLDB and displays correctly using # frame variable and expression commands self.expect('frame variable f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', 'f.op'], patterns = ['0x0+$']) self.expect('frame variable *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops', '*f.op', '<parent is NULL>']) self.expect('expr f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', '$'], patterns = ['0x0+$']) self.expect('expr *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['error:'], error = True) bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect("frame variable day", 'check for valid enumeration value', substrs = [enum_value]) lldbutil.continue_to_breakpoint (self.process(), bkpt)
def do_test(self): """Test the Any type""" exe_name = "a.out" exe = os.path.join(os.getcwd(), exe_name) # Create the target target = self.dbg.CreateTarget(exe) self.assertTrue(target, lldbtest.VALID_TARGET) # Set the breakpoints: bkpt_list = ["main", "takes_class", "takes_struct", "takes_inout"] breakpoints = {} for bkpt_text in bkpt_list: breakpoints[bkpt_text] = target.BreakpointCreateBySourceRegex( 'Break here in ' + bkpt_text, self.main_source_spec) self.assertTrue( breakpoints[bkpt_text].GetNumLocations() > 0, lldbtest.VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. self.process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(self.process, lldbtest.PROCESS_IS_VALID) # Frame #0 should be at our breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( self.process, breakpoints["main"]) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.assertTrue(self.frame.IsValid(), "Frame 0 is valid.") self.check_variable("c", True, 12345) self.check_variable("s", False, 12345) self.check_variable("int", False, 100) threads = lldbutil.continue_to_breakpoint(self.process, breakpoints["takes_class"]) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.check_variable("in_class", True, 12345) threads = lldbutil.continue_to_breakpoint(self.process, breakpoints["takes_struct"]) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.check_variable("in_struct", False, 12345) threads = lldbutil.continue_to_breakpoint(self.process, breakpoints["takes_inout"]) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.check_variable("in_struct", True, 12345)
def test(self): self.build() target, process, _, _ = lldbutil.run_to_name_breakpoint( self, 'main') self.expect("source list -n main", substrs=["Hello Absolute"]) bkpt = target.BreakpointCreateByName('relative') lldbutil.continue_to_breakpoint(process, bkpt) self.expect("source list -n relative", substrs=["Hello Relative"])
def test_namespace_local_var_same_name_cpp_and_c(self): self.build() (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint( self, '// break here', lldb.SBFileSpec("main.cpp", False)) self.expect_expr("error", result_type="int", result_value="1") lldbutil.continue_to_breakpoint(self.process, bkpt) self.expect_expr("error", result_type="int", result_value="1")
def test(self): """Test that a late loaded Swift dylib with Clang dependencies is debuggable""" self.build() target, process, _, _ = lldbutil.run_to_name_breakpoint(self, "main") # Initialize SwiftASTContext before loading the dylib. self.expect("expr -l Swift -- 0") bkpt = target.BreakpointCreateByLocation( lldb.SBFileSpec('dylib.swift'), 5) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("v x", substrs=['42']) self.expect("expr x", substrs=['42'])
def test_namespace_local_var_same_name_obj_c(self): self.build() (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint( self, '// break here', lldb.SBFileSpec("util.mm", False)) self.expect("expr error", substrs=['(NSError *) $0 =']) lldbutil.continue_to_breakpoint(self.process, bkpt) self.expect("expr error", substrs=['(NSError *) $1 ='])
def image_lookup_for_enum_type(self, is_signed): """Test C++11 enumeration class types.""" exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. bkpt_id = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs=[' resolved, hit count = 1']) # Look up information about the 'DayType' enum type. # Check for correct display. self.expect("image lookup -t DayType", DATA_TYPES_DISPLAYED_CORRECTLY, patterns=['enum( struct| class)? DayType {'], substrs=[ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '}' ]) if is_signed: enum_values = [ '-4', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '5' ] else: enum_values = [ '199', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '208' ] bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect("frame variable day", 'check for valid enumeration value', substrs=[enum_value]) lldbutil.continue_to_breakpoint(self.process(), bkpt)
def test_load_after_attach(self): self.build() sync_file_path = lldbutil.append_to_process_working_directory( self, "process_ready") ctx = self.platformContext lib_name = ctx.shlib_prefix + 'lib_b.' + ctx.shlib_extension exe = self.getBuildArtifact("a.out") lib = self.getBuildArtifact(lib_name) target = self.dbg.CreateTarget(exe) environment = self.registerSharedLibrariesWithTarget(target, ["lib_b"]) # Spawn a new process. # use realpath to workaround llvm.org/pr48376 # Pass path to solib for dlopen to properly locate the library. popen = self.spawnSubprocess(os.path.realpath(exe), [sync_file_path], extra_env=environment) lldbutil.wait_for_file_on_target(self, sync_file_path) # Attach to the spawned process. error = lldb.SBError() process = target.AttachToProcessWithID(self.dbg.GetListener(), popen.pid, error) self.assertSuccess(error) # Continue until first breakpoint. breakpoint1 = self.target().BreakpointCreateBySourceRegex( "// break here", lldb.SBFileSpec("main.cpp")) self.assertEqual(breakpoint1.GetNumResolvedLocations(), 1) stopped_threads = lldbutil.continue_to_breakpoint( self.process(), breakpoint1) self.assertEqual(len(stopped_threads), 1) # Change a variable to escape the loop self.runCmd("expression main_thread_continue = 1") # Continue so that dlopen is called. breakpoint2 = self.target().BreakpointCreateBySourceRegex( "// break after dlopen", lldb.SBFileSpec("main.cpp")) self.assertEqual(breakpoint2.GetNumResolvedLocations(), 1) stopped_threads = lldbutil.continue_to_breakpoint( self.process(), breakpoint2) self.assertEqual(len(stopped_threads), 1) # Check that image list contains liblib_b after dlopen. self.match("image list", patterns=[lib_name], matching=True, msg=lib_name + " missing in image list")
def image_lookup_for_enum_type(self): """Test C++11 enumeration class types.""" exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. bkpt_id = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs=[' resolved, hit count = 1']) # Look up information about the 'DayType' enum type. # Check for correct display. self.expect("image lookup -t DayType", DATA_TYPES_DISPLAYED_CORRECTLY, patterns=['enum( struct| class) DayType {'], substrs=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '}']) enum_values = ['-4', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '5'] bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect( "frame variable day", 'check for valid enumeration value', substrs=[enum_value]) lldbutil.continue_to_breakpoint(self.process(), bkpt)
def test_namespace_local_var_same_name_cpp_and_c(self): self.build() (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here', lldb.SBFileSpec("main.cpp", False)) self.expect("expr error", substrs=['(int) $0 = 1']) lldbutil.continue_to_breakpoint(self.process, bkpt) self.expect("expr error", substrs=['(int) $1 = 1'])
def test_ptr_and_ref(self): """Test that ref and ptr to std::bitset is displayed correctly""" self.build() (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint( self, 'Check ref and ptr', lldb.SBFileSpec("main.cpp", False)) self.check("ref", 13) self.check("ptr", 13) lldbutil.continue_to_breakpoint(process, bkpt) self.check("ref", 200) self.check("ptr", 200)
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp( self, "break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) self.runCmd( "frame variable has_optional" ) output = self.res.GetOutput() ## The variable has_optional tells us if the test program ## detected we have a sufficient libc++ version to support optional ## false means we do not and therefore should skip the test if output.find("(bool) has_optional = false") != -1 : self.skipTest( "Optional not supported" ) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable number_not_engaged", substrs=['Has Value=false']) self.expect("frame variable number_engaged", substrs=['Has Value=true', 'Value = 42', '}']) self.expect("frame var numbers", substrs=['(optional_int_vect) numbers = Has Value=true {', 'Value = size=4 {', '[0] = 1', '[1] = 2', '[2] = 3', '[3] = 4', '}', '}']) self.expect("frame var ostring", substrs=['(optional_string) ostring = Has Value=true {', 'Value = "hello"', '}'])
def test_with_run_command(self): """ Test that hardcoded summary formatter matches aren't improperly cached. """ self.build() target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, 'break here', lldb.SBFileSpec('a.c')) valobj = self.frame().FindVariable('f') self.assertEqual(valobj.GetValue(), '4') bkpt_b = target.BreakpointCreateBySourceRegex('break here', lldb.SBFileSpec('b.c')) lldbutil.continue_to_breakpoint(process, bkpt_b) valobj = self.frame().FindVariable('f4') self.assertEqual(valobj.GetSummary(), '(1, 2, 3, 4)')
def suspended_thread_test(self): # Make sure that we don't accept bad values: self.match( "settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_AXESS", "EXC_BAD_AXESS", error=True) # Now set ourselves to ignore some exceptions. The test depends on ignoring EXC_BAD_ACCESS, but I passed a couple # to make sure they parse: self.runCmd( "settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_ACCESS|EXC_ARITHMETIC" ) (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "Stop here to get things going", self.main_source_file) sig_bkpt = target.BreakpointCreateBySourceRegex( "stop here in the signal handler", self.main_source_file) self.assertEqual(sig_bkpt.GetNumLocations(), 1, "Found sig handler breakpoint") return_bkpt = target.BreakpointCreateBySourceRegex( "Break here to make sure we got past the signal handler", self.main_source_file) self.assertEqual(return_bkpt.GetNumLocations(), 1, "Found return breakpoint") # Now continue, and we should stop with a stop reason of SIGBUS: process.Continue() self.assertEqual(process.state, lldb.eStateStopped, "Stopped after continue to SIGBUS") if thread.stop_reason == lldb.eStopReasonBreakpoint: id = thread.GetStopReasonDataAtIndex(0) name = thread.frame[0].name self.fail( "Hit breakpoint {0} in '{1}' rather than getting a SIGBUS". format(id, name)) self.assertEqual(thread.stop_reason, lldb.eStopReasonSignal) self.assertEqual(thread.GetStopReasonDataAtIndex(0), 10, "Got a SIGBUS") # Now when we continue, we'll find our way into the signal handler: threads = lldbutil.continue_to_breakpoint(process, sig_bkpt) self.assertEqual(len(threads), 1, "Stopped at sig breakpoint") threads = lldbutil.continue_to_breakpoint(process, return_bkpt) self.assertEqual(len(threads), 1, "Stopped at return breakpoint") # Make sure we really changed the value: process.Continue() self.assertEqual(process.state, lldb.eStateExited, "Process exited") self.assertEqual(process.exit_state, 20, "Got the right exit status")
def test_ptr_and_ref(self): """Test that ref and ptr to std::bitset is displayed correctly""" self.build() (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, 'Check ref and ptr', lldb.SBFileSpec("main.cpp", False)) self.check("ref", 13) self.check("ptr", 13) lldbutil.continue_to_breakpoint(process, bkpt) self.check("ref", 200) self.check("ptr", 200)
def do_test_ptr_and_ref(self, stdlib_type): """Test that ref and ptr to std::bitset is displayed correctly""" self.build(dictionary={stdlib_type: "1"}) (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint( self, 'Check ref and ptr', lldb.SBFileSpec("main.cpp", False)) self.check("ref", 13, REFERENCE) self.check("ptr", 13, POINTER) lldbutil.continue_to_breakpoint(process, bkpt) self.check("ref", 70, REFERENCE) self.check("ptr", 70, POINTER)
def test(self): """Test the bound generic enum types in "optimized" code.""" self.build() target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, 'break one', lldb.SBFileSpec('main.swift')) bkpt_two = target.BreakpointCreateBySourceRegex( 'break two', lldb.SBFileSpec('main.swift')) self.assertGreater(bkpt_two.GetNumLocations(), 0) var_self = self.frame().FindVariable("self") # FIXME, this fails with a data extractor error. lldbutil.check_variable(self, var_self, False, value=None) lldbutil.continue_to_breakpoint(process, bkpt_two) var_self = self.frame().FindVariable("self") lldbutil.check_variable(self, var_self, True, value="success")
def do_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) self.assertEqual(bkpt.GetNumLocations(), 2, "Got two locations") # So now thread holds the main thread. Continue to hit the # breakpoint again on the spawned thread: threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit the breakpoint the second time") other_thread = threads[0] self.assertNotEqual(thread.GetThreadID(), other_thread.GetThreadID(), "A different thread") # Run an expression ONLY on other_thread. Don't let thread run: options = lldb.SBExpressionOptions() options.SetTryAllThreads(False) options.SetStopOthers(True) result = thread.frames[0].EvaluateExpression( '(int) printf("Hello\\n")', options) self.assertSuccess(result.GetError(), "Expression failed") stop_reason = other_thread.GetStopReason() self.assertEqual( stop_reason, lldb.eStopReasonBreakpoint, "Still records stopped at breakpoint: %s" % (lldbutil.stop_reason_to_str(stop_reason))) self.assertEqual(other_thread.GetStopReasonDataAtIndex(0), 1, "Still records stopped at right breakpoint")
def step_out_test(self, step_out_func): """Test single thread step out of a function.""" (self.inferior_target, self.inferior_process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, self.bkpt_string, lldb.SBFileSpec('main.cpp'), only_one_thread=False) # We hit the breakpoint on at least one thread. If we hit it on both threads # simultaneously, we can try the step out. Otherwise, suspend the thread # that hit the breakpoint, and continue till the second thread hits # the breakpoint: (breakpoint_threads, other_threads) = ([], []) lldbutil.sort_stopped_threads(self.inferior_process, breakpoint_threads=breakpoint_threads, other_threads=other_threads) if len(breakpoint_threads) == 1: success = thread.Suspend() self.assertTrue(success, "Couldn't suspend a thread") bkpt_threads = lldbutil.continue_to_breakpoint(bkpt) self.assertEqual(len(bkpt_threads), 1, "Second thread stopped") success = thread.Resume() self.assertTrue(success, "Couldn't resume a thread") self.step_out_thread = breakpoint_threads[0] # Step out of thread stopped at breakpoint step_out_func()
def step_in_template(self): """Use Python APIs to test stepping in to templated functions.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex ('// Call max_value template', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) break_2_in_main = target.BreakpointCreateBySourceRegex ('// Call max_value specialized', self.main_source_spec) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main) if len(threads) != 1: self.fail ("Failed to stop at first breakpoint in main.") self.thread = threads[0] step_sequence = [["// In max_value template", "into"]] self.run_step_sequence(step_sequence) threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main) self.assertEqual(len(threads), 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [["// In max_value specialized", "into"]] self.run_step_sequence(step_sequence)
def step_in_template(self): """Use Python APIs to test stepping in to templated functions.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex("// Call max_value template", self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) break_2_in_main = target.BreakpointCreateBySourceRegex("// Call max_value specialized", self.main_source_spec) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(self.process, break_1_in_main) if len(threads) != 1: self.fail("Failed to stop at first breakpoint in main.") self.thread = threads[0] step_sequence = [["// In max_value template", "into"]] self.run_step_sequence(step_sequence) threads = lldbutil.continue_to_breakpoint(self.process, break_2_in_main) self.assertEqual(len(threads), 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [["// In max_value specialized", "into"]] self.run_step_sequence(step_sequence)
def test(self): self.build() # Launch and stop before the dlopen call. lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.c")) # Delete the breakpoint we no longer need. self.target().DeleteAllBreakpoints() # Check that the executable is the test binary. self.assertEqual(self.target().GetExecutable().GetFilename(), "a.out") # Continue so that dlopen is called. breakpoint = self.target().BreakpointCreateBySourceRegex( "// break after dlopen", lldb.SBFileSpec("main.c")) self.assertNotEqual(breakpoint.GetNumResolvedLocations(), 0) stopped_threads = lldbutil.continue_to_breakpoint( self.process(), breakpoint) self.assertEqual(len(stopped_threads), 1) # Check that the executable is still the test binary and not "other". self.assertEqual(self.target().GetExecutable().GetFilename(), "a.out") # Kill the process and run the program again. err = self.process().Kill() self.assertSuccess(err) # Test that we hit the breakpoint after dlopen. lldbutil.run_to_breakpoint_do_run(self, self.target(), breakpoint)
def test(self): self.build() lldbutil.run_to_source_breakpoint(self, "// break in static member function", lldb.SBFileSpec("main.cpp")) # Evaluate a static member and call a static member function. self.expect_expr("static_member_var", result_type="int", result_value="2") self.expect_expr("static_const_member_var", result_type="const int", result_value="3") self.expect_expr("static_constexpr_member_var", result_type="const int", result_value="4") self.expect_expr("static_func()", result_type="int", result_value="6") # Check that accessing non-static members just reports a diagnostic. self.expect("expr member_var", error=True, substrs=["invalid use of member 'member_var' in static member function"]) self.expect("expr member_func()", error=True, substrs=["call to non-static member function without an object argument"]) self.expect("expr this", error=True, substrs=["invalid use of 'this' outside of a non-static member function"]) # Continue to a non-static member function of the same class and make # sure that evaluating non-static members now works. breakpoint = self.target().BreakpointCreateBySourceRegex( "// break in member function", lldb.SBFileSpec("main.cpp")) self.assertNotEqual(breakpoint.GetNumResolvedLocations(), 0) stopped_threads = lldbutil.continue_to_breakpoint(self.process(), breakpoint) self.expect_expr("member_var", result_type="int", result_value="1") self.expect_expr("member_func()", result_type="int", result_value="5")
def test_with_python_api(self): """Test stepping through the 'direct dispatch' optimized method calls.""" self.build() (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "Stop here to start stepping", self.main_source) stop_bkpt = target.BreakpointCreateBySourceRegex( "// Stop Location [0-9]+", self.main_source) self.assertEqual(stop_bkpt.GetNumLocations(), 15) # Here we step through all the overridden methods of OverridesALot # The last continue will get us to the call ot OverridesInit. for idx in range(2, 16): thread.StepInto() func_name = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( "OverridesALot" in func_name, "%d'th step did not match name: %s" % (idx, func_name)) stop_threads = lldbutil.continue_to_breakpoint(process, stop_bkpt) self.assertEqual(len(stop_threads), 1) self.assertEqual(stop_threads[0], thread) thread.StepInto() func_name = thread.GetFrameAtIndex(0).GetFunctionName() self.assertEqual(func_name, "-[OverridesInit init]", "Stopped in [OverridesInit init]")
def ignore_vrs_condition(self, use_location): main_spec = lldb.SBFileSpec("main.c") target, process, _, _ = lldbutil.run_to_source_breakpoint( self, self.stop_in_main, main_spec) # Now make a breakpoint on the loop, and set a condition and ignore count. # Make sure that the condition fails don't count against the ignore count. bkpt = target.BreakpointCreateBySourceRegex( "Set a breakpoint here, with i", main_spec) self.assertEqual(bkpt.GetNumLocations(), 1, "Wrong number of locations") if use_location: loc = bkpt.location[0] self.assertTrue(loc.IsValid(), "Got a valid location") loc.SetIgnoreCount(2) loc.SetCondition("i >= 3") else: bkpt.SetIgnoreCount(2) bkpt.SetCondition("i >= 3") threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit the breakpoint") var = threads[0].frame[0].FindVariable("i") self.assertTrue(var.IsValid(), "Didn't find the i variable") val = var.GetValueAsUnsigned(10000) self.assertNotEqual(val, 10000, "Got the fail value for i") self.assertEqual(val, 5, "We didn't stop the right number of times") self.assertEqual(bkpt.GetHitCount(), 3, "Hit count is not right")
def test(self): """Test 'image lookup -t days' and check for correct display and enum value printing.""" self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. bkpt_id = lldbutil.run_break_set_by_file_and_line( self, "main.c", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs=[' resolved, hit count = 1']) # Look up information about the 'days' enum type. # Check for correct display. self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, substrs=[ 'enum days {', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '}' ]) enum_values = [ '-4', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '5' ] bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect("frame variable day", 'check for valid enumeration value', substrs=[enum_value]) lldbutil.continue_to_breakpoint(self.process(), bkpt)
def do_test(self): """Tests that we can break and display simple types""" (target, self.process, self.thread, breakpoint) = lldbutil.run_to_source_breakpoint( self, 'Set breakpoint here', self.main_source_spec) line_before_fin = self.thread.frame[1].line_entry.line self.step_out_until_no_breakpoint(breakpoint, False) # Get a "Swift.Int64" return struct value # Get a "main.Foo" return class value # Get a "Swift.String" return class value # Get a "Swift.Dictionary<Swift.Int, Swift.String>" return class value # Get a "Swift.String?" return class value # Test that the local variable equals return value. # Test that none of the later let-bound values are available. variables = [ "u", "i", "c", "ss", "cs", "s", "dict", "opt_str", "f", "d" ] # FIXME: Enable opt_str below: invisibles = ["i", "c", "s", "dict", "f", "f", "d"] self.do_variables_test(breakpoint, variables, invisibles) # Call a function that could throw but doesn't and see that it actually # gets the result: return_value = self.thread.GetStopReturnValue() if line_before_fin == self.thread.frame[0].line_entry.line: self.thread.StepOver() self.verify_return_value_against_local_variable( return_value, "not_err") # Call it again, but this time it will throw: # The return will be empty, but the error will not be: line_before_fin = self.thread.frame[0].line_entry.line self.step_out_until_no_breakpoint(breakpoint, True) return_value = self.thread.GetStopReturnValue() self.assertTrue(not return_value.IsValid()) error_value = self.thread.GetStopErrorValue() if line_before_fin == self.thread.frame[0].line_entry.line: self.thread.StepOver() self.verify_return_value_against_local_variable(error_value, "err") # Now run the returnBigStruct and step out. We don't know how # to return structs that are passed on the stack for swift right # now, so just make sure that we don't lie about that fact. # When we get this working, move the returnBigStruct to after # returnSmallStruct and put "bs" in the var's array after "ss". # Set the breakpoints another_bkpt = target.BreakpointCreateBySourceRegex( 'Set another breakpoint here', self.main_source_spec) self.assertTrue(another_bkpt.GetNumLocations() > 0, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint(self.process, another_bkpt) self.assertTrue(len(threads) == 1, "Didn't hit another breakpoint") self.thread = threads[0] self.thread.StepOut() return_value = self.thread.GetStopReturnValue() self.assertTrue(not return_value.IsValid())
def test_iterator_formatters(self): """Test that std::unordered_map related structures are formatted correctly when printed. Currently only tests format of std::unordered_map iterators. """ self.build() (self.target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, 'Break here', lldb.SBFileSpec('main.cpp', False)) # Test empty iterators self.expect_expr('empty_iter', '') self.expect_expr('const_empty_iter', '') lldbutil.continue_to_breakpoint(process, bkpt) # Check that key/value is correctly formatted self.expect_expr('foo', result_children=[ ValueCheck(name='first', summary='"Foo"'), ValueCheck(name='second', summary='"Bar"') ]) # Check invalid iterator is empty self.expect_expr('invalid', '') # Const key/val iterator self.expect_expr('const_baz', result_children=[ ValueCheck(name='first', summary='"Baz"'), ValueCheck(name='second', summary='"Qux"') ]) # Bucket iterators # I.e., std::__hash_map_const_iterator<const_local_iterator<...>> # and std::__hash_map_iterator<local_iterator<...>> self.expect_expr('bucket_it', result_children=[ ValueCheck(name='first', summary='"Baz"'), ValueCheck(name='second', summary='"Qux"') ]) self.expect_expr('const_bucket_it', result_children=[ ValueCheck(name='first', summary='"Baz"'), ValueCheck(name='second', summary='"Qux"') ])
def do_profile_and_detach(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) interp = self.dbg.GetCommandInterpreter() result = lldb.SBCommandReturnObject() # First make sure we are getting async data. Set a short interval, continue a bit and check: interp.HandleCommand( "process plugin packet send 'QSetEnableAsyncProfiling;enable:1;interval_usec:500000;scan_type=0x5;'", result) self.assertTrue(result.Succeeded(), "process packet send failed: %s" % (result.GetError())) # Run a bit to give us a change to collect profile data: bkpt.SetIgnoreCount(1) threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit our breakpoint again.") str = process.GetAsyncProfileData(1000) self.assertTrue(len(str) > 0, "Got some profile data") # Now make the profiling interval very long and try to detach. interp.HandleCommand( "process plugin packet send 'QSetEnableAsyncProfiling;enable:1;interval_usec:10000000;scan_type=0x5;'", result) self.assertTrue(result.Succeeded(), "process packet send failed: %s" % (result.GetError())) self.dbg.SetAsync(True) listener = self.dbg.GetListener() # We don't want to hit our breakpoint anymore. bkpt.SetEnabled(False) # Record our process pid so we can kill it since we are going to detach... self.pid = process.GetProcessID() def cleanup(): self.dbg.SetAsync(False) os.kill(self.pid, signal.SIGKILL) self.addTearDownHook(cleanup) process.Continue() event = lldb.SBEvent() success = listener.WaitForEventForBroadcaster(0, process.GetBroadcaster(), event) self.assertTrue(success, "Got an event which should be running.") event_state = process.GetStateFromEvent(event) self.assertEqual(event_state, lldb.eStateRunning, "Got the running event") # Now detach: error = process.Detach() self.assertTrue(error.Success(), "Detached successfully")
def data_formatter_commands(self): """Benchmark different ways to continue a process""" self.runCmd("file "+self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp( self, "// break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd( "settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) runCmd_sw = Stopwatch() lldbutil_sw = Stopwatch() for i in range(0, 15): runCmd_sw.start() self.runCmd("continue") runCmd_sw.stop() for i in range(0, 15): lldbutil_sw.start() lldbutil.continue_to_breakpoint(self.process(), bkpt) lldbutil_sw.stop() print("runCmd: %s\nlldbutil: %s" % (runCmd_sw, lldbutil_sw))
def test(self): """Test lldb exception breakpoint command for CPP.""" self.build() exe = self.getBuildArtifact("a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) exception_bkpt = target.BreakpointCreateForException( lldb.eLanguageTypeC_plus_plus, True, True) self.assertTrue(exception_bkpt, "Made an exception breakpoint") # Now run, and make sure we hit our breakpoint: process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, "Got a valid process") stopped_threads = [] stopped_threads = lldbutil.get_threads_stopped_at_breakpoint( process, exception_bkpt) self.assertTrue( len(stopped_threads) == 1, "Stopped at our exception breakpoint.") thread = stopped_threads[0] # Make sure our throw function is still above us on the stack: frame_functions = lldbutil.get_function_names(thread) self.assertTrue( frame_functions.count("throws_exception_on_even(int)") == 1, "Our throw function is still on the stack.") # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint. # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw. # so loop till we don't see the throws function on the stack. We should stop one more time for our exception breakpoint # and that should be the catch... while frame_functions.count("throws_exception_on_even(int)") == 1: stopped_threads = lldbutil.continue_to_breakpoint( process, exception_bkpt) self.assertTrue(len(stopped_threads) == 1) thread = stopped_threads[0] frame_functions = lldbutil.get_function_names(thread) self.assertTrue( frame_functions.count("throws_exception_on_even(int)") == 0, "At catch our throw function is off the stack") self.assertTrue( frame_functions.count("intervening_function(int)") == 0, "At catch our intervening function is off the stack") self.assertTrue( frame_functions.count("catches_exception(int)") == 1, "At catch our catch function is on the stack")
def test_process_attach_with_wrong_arch(self): """Test that when we attach to a binary from the wrong fork of a universal binary, we fix up the ABI correctly.""" if not haswellOrLater(): return # Now keep the architecture at x86_64, but switch the binary # we launch to x86_64h, and make sure on attach we switch to # the correct architecture. # Invoke the default build rule. self.build() # Note that "testit" is a universal binary. exe = self.getBuildArtifact("testit") # Create a target by the debugger. target = self.dbg.CreateTargetWithFileAndTargetTriple( exe, "x86_64-apple-macosx") self.assertTrue(target, VALID_TARGET) self.expect("image list -A -b", substrs=["x86_64 testit"]) bkpt = target.BreakpointCreateBySourceRegex( "sleep", lldb.SBFileSpec("main.c")) self.assertTrue(bkpt.IsValid(), "Valid breakpoint") self.assertTrue( bkpt.GetNumLocations() >= 1, "Our main breakpoint has locations.") popen = self.spawnSubprocess(exe, ["keep_waiting"]) self.addTearDownHook(self.cleanupSubprocesses) error = lldb.SBError() empty_listener = lldb.SBListener() process = target.AttachToProcessWithID( empty_listener, popen.pid, error) self.assertTrue(error.Success(), "Attached to process.") self.expect("image list -A -b", substrs=["x86_64h testit"]) # It may seem odd to check the number of frames, but the bug # that motivated this test was that we eventually fixed the # architecture, but we left the ABI set to the original value. # In that case, if you asked the process for its architecture, # it would look right, but since the ABI was wrong, # backtracing failed. threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] self.assertTrue( thread.GetNumFrames() > 1, "We were able to backtrace.")
def test_process_attach_with_wrong_arch(self): """Test that when we attach to a binary from the wrong fork of a universal binary, we fix up the ABI correctly.""" # Now keep the architecture at 32 bit, but switch the binary we launch to # 64 bit, and make sure on attach we switch to the correct # architecture. # Invoke the default build rule. self.build() # Note that "testit" is a universal binary. exe = os.path.join(os.getcwd(), "testit") # Create a target by the debugger. target = self.dbg.CreateTargetWithFileAndTargetTriple( exe, "i386-apple-macosx") self.assertTrue(target, VALID_TARGET) pointer_size = target.GetAddressByteSize() self.assertTrue(pointer_size == 4, "Initially we were 32 bit.") bkpt = target.BreakpointCreateBySourceRegex( "sleep", lldb.SBFileSpec("main.c")) self.assertTrue(bkpt.IsValid(), "Valid breakpoint") self.assertTrue( bkpt.GetNumLocations() >= 1, "Our main breakpoint has locations.") popen = self.spawnSubprocess(exe, ["keep_waiting"]) self.addTearDownHook(self.cleanupSubprocesses) error = lldb.SBError() empty_listener = lldb.SBListener() process = target.AttachToProcessWithID( empty_listener, popen.pid, error) self.assertTrue(error.Success(), "Attached to process.") pointer_size = target.GetAddressByteSize() self.assertTrue(pointer_size == 8, "We switched to 64 bit.") # It may seem odd that I am checking the number of frames, but the bug that # motivated this test was that we eventually fixed the architecture, but we # left the ABI set to the original value. In that case, if you asked the # process for its architecture, it would look right, but since the ABI was # wrong, backtracing failed. threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] self.assertTrue( thread.GetNumFrames() > 1, "We were able to backtrace.")
def expr_test(self, trivial): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) # Stop in a function that takes a trivial value, and try both frame var & expr to get its value: if trivial: self.check_frame(thread) return # Now continue to the same thing without the trivial_abi and see if we get that right: threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit my breakpoint the second time.") self.check_frame(threads[0])
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here', lldb.SBFileSpec("main.cpp", False)) self.runCmd( "frame variable has_variant" ) output = self.res.GetOutput() ## The variable has_variant tells us if the test program ## detected we have a sufficient libc++ version to support variant ## false means we do not and therefore should skip the test if output.find("(bool) has_variant = false") != -1 : self.skipTest( "std::variant not supported" ) lldbutil.continue_to_breakpoint(self.process, bkpt) self.expect("frame variable v1", substrs=['v1 = Active Type = int {', 'Value = 12', '}']) self.expect("frame variable v1_ref", substrs=['v1_ref = Active Type = int : {', 'Value = 12', '}']) self.expect("frame variable v_v1", substrs=['v_v1 = Active Type = std::__1::variant<int, double, char> {', 'Value = Active Type = int {', 'Value = 12', '}', '}']) lldbutil.continue_to_breakpoint(self.process, bkpt) self.expect("frame variable v1", substrs=['v1 = Active Type = double {', 'Value = 2', '}']) lldbutil.continue_to_breakpoint(self.process, bkpt) self.expect("frame variable v2", substrs=['v2 = Active Type = double {', 'Value = 2', '}']) self.expect("frame variable v3", substrs=['v3 = Active Type = char {', 'Value = \'A\'', '}']) self.expect("frame variable v_no_value", substrs=['v_no_value = No Value'])
def do_function_starts(self, in_memory): """Run the binary, stop at our unstripped function, make sure the caller has synthetic symbols""" exe = self.getBuildArtifact(exe_name) # Now strip the binary, but leave externals so we can break on dont_strip_me. try: fail_str = system([["strip", "-u", "-x", "-S", exe]]) except CalledProcessError as cmd_error: self.fail("Strip failed: %d"%(cmd_error.returncode)) popen = self.spawnSubprocess(exe) self.addTearDownHook(self.cleanupSubprocesses) if in_memory: remove_file(exe) target = self.dbg.CreateTarget(None) self.assertTrue(target.IsValid(), "Got a vaid empty target.") error = lldb.SBError() attach_info = lldb.SBAttachInfo() attach_info.SetProcessID(popen.pid) attach_info.SetIgnoreExisting(False) process = target.Attach(attach_info, error) self.assertTrue(error.Success(), "Didn't attach successfully to %d: %s"%(popen.pid, error.GetCString())) bkpt = target.BreakpointCreateByName("dont_strip_me", exe) self.assertTrue(bkpt.GetNumLocations() > 0, "Didn't set the dont_strip_me bkpt.") threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.") # Our caller frame should have been stripped. Make sure we made a synthetic symbol # for it: thread = threads[0] self.assertTrue(thread.num_frames > 1, "Couldn't backtrace.") name = thread.frame[1].GetFunctionName() self.assertEqual("___lldb_unnamed_symbol1$$StripMe", name, "Frame name not synthetic")
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() (self.target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "break here", lldb.SBFileSpec("main.cpp", False)) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd( "settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # empty vectors (and storage pointers SHOULD BOTH BE NULL..) self.expect("frame variable numbers", substrs=['numbers = size=0']) lldbutil.continue_to_breakpoint(process, bkpt) # first value added self.expect("frame variable numbers", substrs=['numbers = size=1', '[0] = 1', '}']) # add some more data lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable numbers", substrs=['numbers = size=4', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '}']) self.expect("p numbers", substrs=['$', 'size=4', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '}']) # check access to synthetic children self.runCmd( "type summary add --summary-string \"item 0 is ${var[0]}\" std::int_vect int_vect") self.expect('frame variable numbers', substrs=['item 0 is 1']) self.runCmd( "type summary add --summary-string \"item 0 is ${svar[0]}\" std::int_vect int_vect") self.expect('frame variable numbers', substrs=['item 0 is 1']) # move on with synths self.runCmd("type summary delete std::int_vect") self.runCmd("type summary delete int_vect") # add some more data lldbutil.continue_to_breakpoint(process, bkpt) self.check_numbers("numbers") # clear out the vector and see that we do the right thing once again lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable numbers", substrs=['numbers = size=0']) lldbutil.continue_to_breakpoint(process, bkpt) # first value added self.expect("frame variable numbers", substrs=['numbers = size=1', '[0] = 7', '}']) # check if we can display strings self.expect("frame variable strings", substrs=['goofy', 'is', 'smart']) self.expect("p strings", substrs=['goofy', 'is', 'smart']) # test summaries based on synthetic children self.runCmd( "type summary add std::string_vect string_vect --summary-string \"vector has ${svar%#} items\" -e") self.expect("frame variable strings", substrs=['vector has 3 items', 'goofy', 'is', 'smart']) self.expect("p strings", substrs=['vector has 3 items', 'goofy', 'is', 'smart']) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable strings", substrs=['vector has 4 items']) # check access-by-index self.expect("frame variable strings[0]", substrs=['goofy']) self.expect("frame variable strings[1]", substrs=['is']) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable strings", substrs=['vector has 0 items'])
def do_test(self): """Check that we can examine module globals in the expression parser""" exe_name = "a.out" exe = os.path.join(os.getcwd(), exe_name) # Create the target target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set the breakpoints outer_bkpt = target.BreakpointCreateBySourceRegex( 'Set top_level breakpoint here', self.main_source_spec) self.assertTrue(outer_bkpt.GetNumLocations() > 0, VALID_BREAKPOINT) function_bkpt = target.BreakpointCreateBySourceRegex( 'Set function breakpoint here', self.main_source_spec) self.assertTrue(function_bkpt.GetNumLocations() > 0, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) # Frame #0 should be at our breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, outer_bkpt) self.assertTrue(len(threads) == 1) self.thread = threads[0] # All the variables should be uninitialized at this point. Maybe sure # they look that way: frame = self.thread.frames[0] options = lldb.SBExpressionOptions() options.SetFetchDynamicValue(lldb.eDynamicCanRunTarget) error = lldb.SBError() # Examine the variables before initialization: g_counter = frame.EvaluateExpression("g_counter", options) self.assertTrue( g_counter.IsValid(), "g_counter returned a valid value object.") value = g_counter.GetValueAsSigned(error) self.assertTrue(error.Success(), "Got a value for g_counter") self.assertTrue( value == 0, "g_counter value is the uninitialized one.") foo_var = frame.EvaluateExpression("my_foo", options) self.assertTrue( foo_var.IsValid(), "foo_var returned a valid value object.") value = foo_var.GetValueAsUnsigned(error) self.assertTrue(error.Success(), "foo_var has a value.") self.assertTrue(value == 0, "foo_var is null before initialization.") my_large_dude = frame.EvaluateExpression("my_large_dude", options) self.assertTrue(my_large_dude.IsValid(), "my_large_dude returned a valid value object.") value = my_large_dude.GetValue() self.assertTrue(error.Success(), "Got a value for my_large_dude") self.assertTrue( value is None, "my_large_dude value is the uninitialized one.") # Now proceed to the breakpoint in our main function, make sure we can # still read these variables and they now have the right values. threads = lldbutil.continue_to_breakpoint(process, function_bkpt) self.assertTrue(len(threads) == 1) self.thread = threads[0] # Examine the variables before initialization: g_counter = frame.EvaluateExpression("g_counter", options) self.assertTrue( g_counter.IsValid(), "g_counter returned a valid value object.") value = g_counter.GetValueAsSigned(error) self.assertTrue(error.Success(), "Got a value for g_counter") self.assertTrue(value == 2, "g_counter value should be 2.") foo_var = frame.EvaluateExpression("my_foo", options) self.assertTrue( foo_var.IsValid(), "foo_var returned a valid value object.") foo_var_x = foo_var.GetChildMemberWithName("x") self.assertTrue(foo_var_x.IsValid(), "Got value object for foo_var.x") value = foo_var_x.GetValueAsUnsigned(error) self.assertTrue(error.Success(), "foo_var.x has a value.") self.assertTrue(value == 1, "foo_var is null before initialization.") my_large_dude = frame.EvaluateExpression("my_large_dude", options) self.assertTrue(my_large_dude.IsValid(), "my_large_dude returned a valid value object.") my_large_dude_y = my_large_dude.GetChildMemberWithName("y") self.assertTrue( my_large_dude_y.IsValid(), "Got value object for my_large_dude.y") value = my_large_dude_y.GetValueAsUnsigned(error) self.assertTrue(error.Success(), "Got a value for my_large_dude.y") self.assertTrue( value == 20, "my_large_dude value is the uninitialized one.")
def test_get_objc_dynamic_vals(self): """Test fetching ObjC dynamic values.""" if self.getArchitecture() == 'i386': # rdar://problem/9946499 self.skipTest("Dynamic types for ObjC V1 runtime not implemented") self.build() exe = self.getBuildArtifact("a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: handle_SourceBase_bkpt = target.BreakpointCreateByLocation( self.source_name, self.handle_SourceBase) self.assertTrue(handle_SourceBase_bkpt and handle_SourceBase_bkpt.GetNumLocations() == 1, VALID_BREAKPOINT) main_before_setProperty_bkpt = target.BreakpointCreateByLocation( self.source_name, self.main_before_setProperty_line) self.assertTrue(main_before_setProperty_bkpt and main_before_setProperty_bkpt.GetNumLocations() == 1, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) threads = lldbutil.get_threads_stopped_at_breakpoint( process, main_before_setProperty_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] # # At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived # make sure we can get that properly: frame = thread.GetFrameAtIndex(0) myObserver = frame.FindVariable( 'myObserver', lldb.eDynamicCanRunTarget) self.assertTrue(myObserver) myObserver_source = myObserver.GetChildMemberWithName( '_source', lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr(myObserver_source) # # Make sure a static value can be correctly turned into a dynamic # value. frame = thread.GetFrameAtIndex(0) myObserver_static = frame.FindVariable( 'myObserver', lldb.eNoDynamicValues) self.assertTrue(myObserver_static) myObserver = myObserver_static.GetDynamicValue( lldb.eDynamicCanRunTarget) myObserver_source = myObserver.GetChildMemberWithName( '_source', lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr(myObserver_source) # The "frame var" code uses another path to get into children, so let's # make sure that works as well: result = lldb.SBCommandReturnObject() self.expect( 'frame var -d run-target myObserver->_source', 'frame var finds its way into a child member', patterns=['\(SourceDerived \*\)']) # check that our ObjC GetISA() does a good job at hiding KVO swizzled # classes self.expect( 'frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden', substrs=['SourceDerived']) self.expect( 'frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden', matching=False, substrs=['NSKVONotify']) # This test is not entirely related to the main thrust of this test case, but since we're here, # try stepping into setProperty, and make sure we get into the version # in Source: thread.StepInto() threads = lldbutil.get_stopped_threads( process, lldb.eStopReasonPlanComplete) self.assertTrue(len(threads) == 1) line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry() self.assertEqual(line_entry.GetLine(), self.set_property_line) self.assertEqual( line_entry.GetFileSpec().GetFilename(), self.source_name) # Okay, back to the main business. Continue to the handle_SourceBase # and make sure we get the correct dynamic value. threads = lldbutil.continue_to_breakpoint( process, handle_SourceBase_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "object" using FindVariable: noDynamic = lldb.eNoDynamicValues useDynamic = lldb.eDynamicCanRunTarget object_static = frame.FindVariable('object', noDynamic) object_dynamic = frame.FindVariable('object', useDynamic) # Delete this object to make sure that this doesn't cause havoc with # the dynamic object that depends on it. del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Get "this" using FindValue, make sure that works too: object_static = frame.FindValue( 'object', lldb.eValueTypeVariableArgument, noDynamic) object_dynamic = frame.FindValue( 'object', lldb.eValueTypeVariableArgument, useDynamic) del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Get "this" using the EvaluateExpression: object_static = frame.EvaluateExpression('object', noDynamic) object_dynamic = frame.EvaluateExpression('object', useDynamic) del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Continue again to the handle_SourceBase and make sure we get the correct dynamic value. # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so # its isa pointer points to SourceBase not NSKVOSourceBase or # whatever... threads = lldbutil.continue_to_breakpoint( process, handle_SourceBase_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "object" using FindVariable: object_static = frame.FindVariable('object', noDynamic) object_dynamic = frame.FindVariable('object', useDynamic) # Delete this object to make sure that this doesn't cause havoc with # the dynamic object that depends on it. del (object_static) self.examine_SourceDerived_ptr(object_dynamic)
def test_and_python_api(self): """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec(self.main_source) breakpoints_to_disable = [] break_1_in_main = target.BreakpointCreateBySourceRegex( '// frame select 2, thread step-out while stopped at .c.1..', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) breakpoints_to_disable.append(break_1_in_main) break_in_a = target.BreakpointCreateBySourceRegex( '// break here to stop in a before calling b', self.main_source_spec) self.assertTrue(break_in_a, VALID_BREAKPOINT) breakpoints_to_disable.append(break_in_a) break_in_b = target.BreakpointCreateBySourceRegex( '// thread step-out while stopped at .c.2..', self.main_source_spec) self.assertTrue(break_in_b, VALID_BREAKPOINT) breakpoints_to_disable.append(break_in_b) break_in_c = target.BreakpointCreateBySourceRegex( '// Find the line number of function .c. here.', self.main_source_spec) self.assertTrue(break_in_c, VALID_BREAKPOINT) breakpoints_to_disable.append(break_in_c) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_1_in_main) if len(threads) != 1: self.fail("Failed to stop at first breakpoint in main.") thread = threads[0] # Get the stop id and for fun make sure it increases: old_stop_id = process.GetStopID() # Now step over, which should cause us to hit the breakpoint in "a" thread.StepOver() # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_a) if len(threads) != 1: self.fail("Failed to stop at breakpoint in a.") # Check that the stop ID increases: new_stop_id = process.GetStopID() self.assertTrue( new_stop_id > old_stop_id, "Stop ID increases monotonically.") thread = threads[0] # Step over, and we should hit the breakpoint in b: thread.StepOver() threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_b) if len(threads) != 1: self.fail("Failed to stop at breakpoint in b.") thread = threads[0] # Now try running some function, and make sure that we still end up in the same place # and with the same stop reason. frame = thread.GetFrameAtIndex(0) current_line = frame.GetLineEntry().GetLine() current_file = frame.GetLineEntry().GetFileSpec() current_bp = [] current_bp.append(thread.GetStopReasonDataAtIndex(0)) current_bp.append(thread.GetStopReasonDataAtIndex(1)) stop_id_before_expression = process.GetStopID() stop_id_before_including_expressions = process.GetStopID(True) frame.EvaluateExpression("(int) printf (print_string)") frame = thread.GetFrameAtIndex(0) self.assertTrue( current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") self.assertTrue( current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") self.assertTrue( thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") self.assertTrue(thread.GetStopReasonDataAtIndex(0) == current_bp[ 0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") # Also make sure running the expression didn't change the public stop id # but did change if we are asking for expression stops as well. stop_id_after_expression = process.GetStopID() stop_id_after_including_expressions = process.GetStopID(True) self.assertTrue( stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID") self.assertTrue( stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.") # Do the same thing with an expression that's going to crash, and make # sure we are still unchanged. frame.EvaluateExpression("((char *) 0)[0] = 'a'") frame = thread.GetFrameAtIndex(0) self.assertTrue( current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") self.assertTrue( current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") self.assertTrue( thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") self.assertTrue(thread.GetStopReasonDataAtIndex(0) == current_bp[ 0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") # Now continue and make sure we just complete the step: # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the # breakpoint a "b" and we don't want to hit that. for bkpt in breakpoints_to_disable: bkpt.SetEnabled(False) process.Continue() self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "a") self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) # And one more time should get us back to main: process.Continue() self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main") self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) # Now make sure we can call a function, break in the called function, # then have "continue" get us back out again: frame = thread.GetFrameAtIndex(0) frame = thread.GetFrameAtIndex(0) current_line = frame.GetLineEntry().GetLine() current_file = frame.GetLineEntry().GetFileSpec() break_in_b.SetEnabled(True) options = lldb.SBExpressionOptions() options.SetIgnoreBreakpoints(False) options.SetFetchDynamicValue(False) options.SetUnwindOnError(False) frame.EvaluateExpression("b (4)", options) threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_b) if len(threads) != 1: self.fail("Failed to stop at breakpoint in b when calling b.") thread = threads[0] # So do a step over here to make sure we can still do that: thread.StepOver() # See that we are still in b: func_name = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( func_name == "b", "Should be in 'b', were in %s" % (func_name)) # Okay, now if we continue, we will finish off our function call and we # should end up back in "a" as if nothing had happened: process.Continue() self.assertTrue(thread.GetFrameAtIndex( 0).GetLineEntry().GetLine() == current_line) self.assertTrue(thread.GetFrameAtIndex( 0).GetLineEntry().GetFileSpec() == current_file) # Now we are going to test step in targeting a function: break_in_b.SetEnabled(False) break_before_complex_1 = target.BreakpointCreateBySourceRegex( '// Stop here to try step in targeting b.', self.main_source_spec) self.assertTrue(break_before_complex_1, VALID_BREAKPOINT) break_before_complex_2 = target.BreakpointCreateBySourceRegex( '// Stop here to try step in targeting complex.', self.main_source_spec) self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) break_before_complex_3 = target.BreakpointCreateBySourceRegex( '// Stop here to step targeting b and hitting breakpoint.', self.main_source_spec) self.assertTrue(break_before_complex_3, VALID_BREAKPOINT) break_before_complex_4 = target.BreakpointCreateBySourceRegex( '// Stop here to make sure bogus target steps over.', self.main_source_spec) self.assertTrue(break_before_complex_4, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint( process, break_before_complex_1) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_1.SetEnabled(False) thread.StepInto("b") self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Now continue out and stop at the next call to complex. This time # step all the way into complex: threads = lldbutil.continue_to_breakpoint( process, break_before_complex_2) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_2.SetEnabled(False) thread.StepInto("complex") self.assertTrue(thread.GetFrameAtIndex( 0).GetFunctionName() == "complex") # Now continue out and stop at the next call to complex. This time # enable breakpoints in a and c and then step targeting b: threads = lldbutil.continue_to_breakpoint( process, break_before_complex_3) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_3.SetEnabled(False) break_at_start_of_a = target.BreakpointCreateByName('a') break_at_start_of_c = target.BreakpointCreateByName('c') thread.StepInto("b") threads = lldbutil.get_stopped_threads( process, lldb.eStopReasonBreakpoint) self.assertTrue(len(threads) == 1) thread = threads[0] stop_break_id = thread.GetStopReasonDataAtIndex(0) self.assertTrue(stop_break_id == break_at_start_of_a.GetID() or stop_break_id == break_at_start_of_c.GetID()) break_at_start_of_a.SetEnabled(False) break_at_start_of_c.SetEnabled(False) process.Continue() self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Now continue out and stop at the next call to complex. This time # enable breakpoints in a and c and then step targeting b: threads = lldbutil.continue_to_breakpoint( process, break_before_complex_4) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_4.SetEnabled(False) thread.StepInto("NoSuchFunction") self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main")
def continue_to_bkpt(self, process, bkpt): threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.assertTrue(self.frame, "Frame 0 is valid.")
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+")) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp(self, "break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=["stopped", "stop reason = breakpoint"]) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd("type format clear", check=False) self.runCmd("type summary clear", check=False) self.runCmd("type filter clear", check=False) self.runCmd("type synth clear", check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # empty vectors (and storage pointers SHOULD BOTH BE NULL..) self.expect("frame variable numbers", substrs=["numbers = size=0"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) # first value added self.expect("frame variable numbers", substrs=["numbers = size=1", "[0] = 1", "}"]) # add some more data lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect( "frame variable numbers", substrs=["numbers = size=4", "[0] = 1", "[1] = 12", "[2] = 123", "[3] = 1234", "}"], ) self.expect("p numbers", substrs=["$", "size=4", "[0] = 1", "[1] = 12", "[2] = 123", "[3] = 1234", "}"]) # check access to synthetic children self.runCmd('type summary add --summary-string "item 0 is ${var[0]}" std::int_vect int_vect') self.expect("frame variable numbers", substrs=["item 0 is 1"]) self.runCmd('type summary add --summary-string "item 0 is ${svar[0]}" std::int_vect int_vect') self.expect("frame variable numbers", substrs=["item 0 is 1"]) # move on with synths self.runCmd("type summary delete std::int_vect") self.runCmd("type summary delete int_vect") # add some more data lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect( "frame variable numbers", substrs=[ "numbers = size=7", "[0] = 1", "[1] = 12", "[2] = 123", "[3] = 1234", "[4] = 12345", "[5] = 123456", "[6] = 1234567", "}", ], ) self.expect( "p numbers", substrs=[ "$", "size=7", "[0] = 1", "[1] = 12", "[2] = 123", "[3] = 1234", "[4] = 12345", "[5] = 123456", "[6] = 1234567", "}", ], ) # check access-by-index self.expect("frame variable numbers[0]", substrs=["1"]) self.expect("frame variable numbers[1]", substrs=["12"]) self.expect("frame variable numbers[2]", substrs=["123"]) self.expect("frame variable numbers[3]", substrs=["1234"]) # clear out the vector and see that we do the right thing once again lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs=["numbers = size=0"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) # first value added self.expect("frame variable numbers", substrs=["numbers = size=1", "[0] = 7", "}"]) # check if we can display strings self.expect("frame variable strings", substrs=["goofy", "is", "smart"]) self.expect("p strings", substrs=["goofy", "is", "smart"]) # test summaries based on synthetic children self.runCmd('type summary add std::string_vect string_vect --summary-string "vector has ${svar%#} items" -e') self.expect("frame variable strings", substrs=["vector has 3 items", "goofy", "is", "smart"]) self.expect("p strings", substrs=["vector has 3 items", "goofy", "is", "smart"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable strings", substrs=["vector has 4 items"]) # check access-by-index self.expect("frame variable strings[0]", substrs=["goofy"]) self.expect("frame variable strings[1]", substrs=["is"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable strings", substrs=["vector has 0 items"])
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() (self.target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( self, "Set break point at this line.", lldb.SBFileSpec("main.cpp", False)) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd( "settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) ii_type = self.getVariableType("ii") self.assertTrue(ii_type.startswith(self.namespace + "::set"), "Type: " + ii_type) self.expect("frame variable ii", substrs=["size=0", "{}"]) lldbutil.continue_to_breakpoint(process, bkpt) self.expect( "frame variable ii", substrs=["size=6", "[0] = 0", "[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"]) lldbutil.continue_to_breakpoint(process, bkpt) self.check_ii("ii") lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable ii", substrs=["size=0", "{}"]) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("frame variable ii", substrs=["size=0", "{}"]) ss_type = self.getVariableType("ss") self.assertTrue(ii_type.startswith(self.namespace + "::set"), "Type: " + ss_type) self.expect("frame variable ss", substrs=["size=0", "{}"]) lldbutil.continue_to_breakpoint(process, bkpt) self.expect( "frame variable ss", substrs=["size=2", '[0] = "a"', '[1] = "a very long string is right here"']) lldbutil.continue_to_breakpoint(process, bkpt) self.expect( "frame variable ss", substrs=["size=4", '[2] = "b"', '[3] = "c"', '[0] = "a"', '[1] = "a very long string is right here"']) self.expect( "p ss", substrs=["size=4", '[2] = "b"', '[3] = "c"', '[0] = "a"', '[1] = "a very long string is right here"']) self.expect("frame variable ss[2]", substrs=[' = "b"']) lldbutil.continue_to_breakpoint(process, bkpt) self.expect( "frame variable ss", substrs=["size=3", '[0] = "a"', '[1] = "a very long string is right here"', '[2] = "c"'])
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp( self, "Set break point at this line.")) self.runCmd("run", RUN_SUCCEEDED) lldbutil.skip_if_library_missing( self, self.target(), lldbutil.PrintableRegex("libc\+\+")) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd( "settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect('image list', substrs=self.getLibcPlusPlusLibs()) self.expect('frame variable ii', substrs=['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs=['size=2', '[0] = ', 'first = 0', 'second = 0', '[1] = ', 'first = 1', 'second = 1']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs=['size=4', '[2] = ', 'first = 2', 'second = 0', '[3] = ', 'first = 3', 'second = 1']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs=['size=8', '[5] = ', 'first = 5', 'second = 0', '[7] = ', 'first = 7', 'second = 1']) self.expect("p ii", substrs=['size=8', '[5] = ', 'first = 5', 'second = 0', '[7] = ', 'first = 7', 'second = 1']) # check access-by-index self.expect("frame variable ii[0]", substrs=['first = 0', 'second = 0']) self.expect("frame variable ii[3]", substrs=['first =', 'second =']) # check that MightHaveChildren() gets it right self.assertTrue( self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!") # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being # self.expect("expression ii[8]", matching=False, error=True, # substrs = ['1234567']) self.runCmd("continue") self.expect('frame variable ii', substrs=['size=0', '{}']) self.expect('frame variable si', substrs=['size=0', '{}']) self.runCmd("continue") self.expect('frame variable si', substrs=['size=1', '[0] = ', 'first = \"zero\"', 'second = 0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable si", substrs=['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', '[1] = ', 'first = \"one\"', 'second = 1', '[2] = ', 'first = \"two\"', 'second = 2', '[3] = ', 'first = \"three\"', 'second = 3']) self.expect("p si", substrs=['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', '[1] = ', 'first = \"one\"', 'second = 1', '[2] = ', 'first = \"two\"', 'second = 2', '[3] = ', 'first = \"three\"', 'second = 3']) # check that MightHaveChildren() gets it right self.assertTrue( self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable si[0]", substrs=['first = ', 'one', 'second = 1']) # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being # self.expect("expression si[0]", matching=False, error=True, # substrs = ['first = ', 'zero']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable si', substrs=['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable is', substrs=['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable is", substrs=['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', '[1] = ', 'second = \"is\"', 'first = 1', '[2] = ', 'second = \"smart\"', 'first = 2', '[3] = ', 'second = \"!!!\"', 'first = 3']) self.expect("p is", substrs=['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', '[1] = ', 'second = \"is\"', 'first = 1', '[2] = ', 'second = \"smart\"', 'first = 2', '[3] = ', 'second = \"!!!\"', 'first = 3']) # check that MightHaveChildren() gets it right self.assertTrue( self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable is[0]", substrs=['first = ', 'second =']) # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being # self.expect("expression is[0]", matching=False, error=True, # substrs = ['first = ', 'goofy']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable is', substrs=['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ss', substrs=['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs=['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', '[1] = ', 'second = \"house\"', 'first = \"casa\"', '[2] = ', 'second = \"cat\"', 'first = \"gatto\"']) self.expect("p ss", substrs=['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', '[1] = ', 'second = \"house\"', 'first = \"casa\"', '[2] = ', 'second = \"cat\"', 'first = \"gatto\"']) # check that MightHaveChildren() gets it right self.assertTrue( self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable ss[2]", substrs=['gatto', 'cat']) # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being # self.expect("expression ss[3]", matching=False, error=True, # substrs = ['gatto']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ss', substrs=['size=0', '{}'])
def test_with_python_api(self): """Test stepping through ObjC method dispatch in various forms.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec (self.main_source) breakpoints_to_disable = [] break1 = target.BreakpointCreateBySourceRegex ("// Set first breakpoint here.", self.main_source_spec) self.assertTrue(break1, VALID_BREAKPOINT) breakpoints_to_disable.append (break1) break2 = target.BreakpointCreateBySourceRegex ("// Set second breakpoint here.", self.main_source_spec) self.assertTrue(break2, VALID_BREAKPOINT) breakpoints_to_disable.append (break2) break3 = target.BreakpointCreateBySourceRegex ('// Set third breakpoint here.', self.main_source_spec) self.assertTrue(break3, VALID_BREAKPOINT) breakpoints_to_disable.append (break3) break4 = target.BreakpointCreateBySourceRegex ('// Set fourth breakpoint here.', self.main_source_spec) self.assertTrue(break4, VALID_BREAKPOINT) breakpoints_to_disable.append (break4) break5 = target.BreakpointCreateBySourceRegex ('// Set fifth breakpoint here.', self.main_source_spec) self.assertTrue(break5, VALID_BREAKPOINT) breakpoints_to_disable.append (break5) break_returnStruct_call_super = target.BreakpointCreateBySourceRegex ('// Source returnsStruct call line.', self.main_source_spec) self.assertTrue(break_returnStruct_call_super, VALID_BREAKPOINT) breakpoints_to_disable.append (break_returnStruct_call_super) break_step_nil = target.BreakpointCreateBySourceRegex ('// Set nil step breakpoint here.', self.main_source_spec) self.assertTrue(break_step_nil, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (process, break1) if len(threads) != 1: self.fail ("Failed to stop at breakpoint 1.") thread = threads[0] mySource = thread.GetFrameAtIndex(0).FindVariable("mySource") self.assertTrue(mySource, "Found mySource local variable.") mySource_isa = mySource.GetChildMemberWithName ("isa") self.assertTrue(mySource_isa, "Found mySource->isa local variable.") className = mySource_isa.GetSummary () if self.TraceOn(): print(mySource_isa) # Lets delete mySource so we can check that after stepping a child variable # with no parent persists and is useful. del (mySource) # Now step in, that should leave us in the Source randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod.") # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod.") threads = lldbutil.continue_to_breakpoint (process, break2) self.assertTrue (len(threads) == 1, "Continued to second breakpoint in main.") # Again, step in twice gets us to a stret method and a stret super call: thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct.") threads = lldbutil.continue_to_breakpoint (process, break_returnStruct_call_super) self.assertTrue (len(threads) == 1, "Stepped to the call super line in Source returnsStruct.") thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct.") # Cool now continue to get past the call that initializes the Observer, and then do our steps in again to see that # we can find our way when we're stepping through a KVO swizzled object. threads = lldbutil.continue_to_breakpoint (process, break3) self.assertTrue (len(threads) == 1, "Continued to third breakpoint in main, our object should now be swizzled.") newClassName = mySource_isa.GetSummary () if self.TraceOn(): print(mySource_isa) self.assertTrue (newClassName != className, "The isa did indeed change, swizzled!") # Now step in, that should leave us in the Source randomMethod: thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod in swizzled object.") # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod in swizzled object.") threads = lldbutil.continue_to_breakpoint (process, break4) self.assertTrue (len(threads) == 1, "Continued to fourth breakpoint in main.") thread = threads[0] # Again, step in twice gets us to a stret method and a stret super call: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct in swizzled object.") threads = lldbutil.continue_to_breakpoint(process, break_returnStruct_call_super) self.assertTrue (len(threads) == 1, "Stepped to the call super line in Source returnsStruct - second time.") thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct in swizzled object.") for bkpt in breakpoints_to_disable: bkpt.SetEnabled(False) threads = lldbutil.continue_to_breakpoint (process, break_step_nil) self.assertTrue (len(threads) == 1, "Continued to step nil breakpoint.") thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.stepped_past_nil_line, "Step in over dispatch to nil stepped over.")
def test_with_python_api(self): """Test stepping and setting breakpoints in indirect and re-exported symbols.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec(self.main_source) break1 = target.BreakpointCreateBySourceRegex( "Set breakpoint here to step in indirect.", self.main_source_spec) self.assertTrue(break1, VALID_BREAKPOINT) break2 = target.BreakpointCreateBySourceRegex( "Set breakpoint here to step in reexported.", self.main_source_spec) self.assertTrue(break2, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) if len(threads) != 1: self.fail("Failed to stop at breakpoint 1.") thread = threads[0] # Now do a step-into, and we should end up in the hidden target of this # indirect function. thread.StepInto() curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # Now set a breakpoint using the indirect symbol name, and make sure we # get to that: break_indirect = target.BreakpointCreateByName("call_through_indirect") self.assertTrue(break_indirect, VALID_BREAKPOINT) # Now continue should take us to the second call through the indirect # symbol: threads = lldbutil.continue_to_breakpoint(process, break_indirect) self.assertTrue( len(threads) == 1, "Stopped at breakpoint in indirect function.") curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # Delete this breakpoint so it won't get in the way: target.BreakpointDelete(break_indirect.GetID()) # Now continue to the site of the first re-exported function call in # main: threads = lldbutil.continue_to_breakpoint(process, break2) # This is stepping Into through a re-exported symbol to an indirect # symbol: thread.StepInto() curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # And the last bit is to set a breakpoint on the re-exported symbol and # make sure we are again in out target function. break_reexported = target.BreakpointCreateByName( "reexport_to_indirect") self.assertTrue(break_reexported, VALID_BREAKPOINT) # Now continue should take us to the second call through the indirect # symbol: threads = lldbutil.continue_to_breakpoint(process, break_reexported) self.assertTrue( len(threads) == 1, "Stopped at breakpoint in reexported function target.") curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.")
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")) self.runCmd("run", RUN_SUCCEEDED) lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+")) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect('image list', substrs = self.getLibcPlusPlusLibs()) self.expect("frame variable ii",substrs = ["size=0","{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) self.expect("frame variable ii[2]",substrs = [" = 2"]) self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=0","{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=0","{}"]) self.expect("frame variable ss",substrs = ["size=0","{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) self.expect("frame variable ss[2]",substrs = [' = "b"']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
def do_sbvalue_cast (self, exe_name): """Test SBValue::Cast(SBType) API for C++ types.""" exe = os.path.join(os.getcwd(), exe_name) # Create a target from the debugger. target = self.dbg.CreateTarget (exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) # Find DerivedA and DerivedB types. typeA = target.FindFirstType('DerivedA') typeB = target.FindFirstType('DerivedB') self.DebugSBType(typeA) self.DebugSBType(typeB) self.assertTrue(typeA) self.assertTrue(typeB) error = lldb.SBError() # First stop is for DerivedA instance. threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) self.assertTrue (len(threads) == 1) thread = threads[0] frame0 = thread.GetFrameAtIndex(0) tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues) self.DebugSBValue(tellerA) self.assertTrue(tellerA.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 20) if self.TraceOn(): for child in tellerA: print("child name:", child.GetName()) print(child) # Call SBValue.Cast() to obtain instanceA. instanceA = tellerA.Cast(typeA.GetPointerType()) self.DebugSBValue(instanceA) # Iterate through all the children and print their values. if self.TraceOn(): for child in instanceA: print("child name:", child.GetName()) print(child) a_member_val = instanceA.GetChildMemberWithName('m_a_val') self.DebugSBValue(a_member_val) self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10) # Second stop is for DerivedB instance. threads = lldbutil.continue_to_breakpoint (process, breakpoint) self.assertTrue (len(threads) == 1) thread = threads[0] frame0 = thread.GetFrameAtIndex(0) tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues) self.DebugSBValue(tellerB) self.assertTrue(tellerB.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 12) if self.TraceOn(): for child in tellerB: print("child name:", child.GetName()) print(child) # Call SBValue.Cast() to obtain instanceB. instanceB = tellerB.Cast(typeB.GetPointerType()) self.DebugSBValue(instanceB) # Iterate through all the children and print their values. if self.TraceOn(): for child in instanceB: print("child name:", child.GetName()) print(child) b_member_val = instanceB.GetChildMemberWithName('m_b_val') self.DebugSBValue(b_member_val) self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36)
def inline_stepping(self): """Use Python APIs to test stepping over and hitting breakpoints.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex( "// Stop here and step over to set up stepping over.", self.main_source_spec ) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(self.process, break_1_in_main) if len(threads) != 1: self.fail("Failed to stop at first breakpoint in main.") self.thread = threads[0] # Step over the inline_value = 0 line to get us to inline_trivial_1 called from main. Doing it this way works # around a bug in lldb where the breakpoint on the containing line of an inlined function with no return value # gets set past the insertion line in the function. # Then test stepping over a simple inlined function. Note, to test all the parts of the inlined stepping # the calls inline_stepping_1 and inline_stepping_2 should line up at the same address, that way we will test # the "virtual" stepping. # FIXME: Put in a check to see if that is true and warn if it is not. step_sequence = [ ["// At inline_trivial_1 called from main.", "over"], ["// At first call of caller_trivial_1 in main.", "over"], ] self.run_step_sequence(step_sequence) # Now step from caller_ref_1 all the way into called_by_inline_trivial step_sequence = [ ["// In caller_trivial_1.", "into"], ["// In caller_trivial_2.", "into"], ["// In inline_trivial_1.", "into"], ["// In inline_trivial_2.", "into"], ["// At caller_by_inline_trivial in inline_trivial_2.", "over"], ["// In called_by_inline_trivial.", "into"], ] self.run_step_sequence(step_sequence) # Now run to the inline_trivial_1 just before the immediate step into inline_trivial_2: break_2_in_main = target.BreakpointCreateBySourceRegex( "// At second call of caller_trivial_1 in main.", self.main_source_spec ) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint(self.process, break_2_in_main) self.assertTrue(len(threads) == 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [ ["// In caller_trivial_1.", "into"], ["// In caller_trivial_2.", "into"], ["// In inline_trivial_1.", "into"], ] self.run_step_sequence(step_sequence) # Then call some trivial function, and make sure we end up back where we were in the inlined call stack: frame = self.thread.GetFrameAtIndex(0) before_line_entry = frame.GetLineEntry() value = frame.EvaluateExpression("function_to_call()") after_line_entry = frame.GetLineEntry() self.assertTrue( before_line_entry.GetLine() == after_line_entry.GetLine(), "Line entry before and after function calls are the same.", ) # Now make sure stepping OVER in the middle of the stack works, and then check finish from the inlined frame: step_sequence = [ ["// At increment in inline_trivial_1.", "over"], ["// At increment in caller_trivial_2.", "out"], ] self.run_step_sequence(step_sequence) # Now run to the place in main just before the first call to caller_ref_1: break_3_in_main = target.BreakpointCreateBySourceRegex( "// At first call of caller_ref_1 in main.", self.main_source_spec ) self.assertTrue(break_3_in_main, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint(self.process, break_3_in_main) self.assertTrue(len(threads) == 1, "Successfully ran to call site of first caller_ref_1 call.") self.thread = threads[0] step_sequence = [ ["// In caller_ref_1.", "into"], ["// In caller_ref_2.", "into"], ["// In inline_ref_1.", "into"], ["// In inline_ref_2.", "into"], ["// In called_by_inline_ref.", "into"], ["// In inline_ref_2.", "out"], ["// In inline_ref_1.", "out"], ["// At increment in inline_ref_1.", "over"], ["// In caller_ref_2.", "out"], ["// At increment in caller_ref_2.", "over"], ] self.run_step_sequence(step_sequence)
def test_get_dynamic_vals(self): """Test fetching C++ dynamic values from pointers & references.""" self.build(dictionary=self.getBuildFlags()) exe = self.getBuildArtifact("a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: do_something_bpt = target.BreakpointCreateByLocation( 'pass-to-base.cpp', self.do_something_line) self.assertTrue(do_something_bpt, VALID_BREAKPOINT) first_call_bpt = target.BreakpointCreateByLocation( 'pass-to-base.cpp', self.main_first_call_line) self.assertTrue(first_call_bpt, VALID_BREAKPOINT) second_call_bpt = target.BreakpointCreateByLocation( 'pass-to-base.cpp', self.main_second_call_line) self.assertTrue(second_call_bpt, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) threads = lldbutil.get_threads_stopped_at_breakpoint( process, first_call_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Now find the dynamic addresses of myB and otherB so we can compare them # with the dynamic values we get in doSomething: use_dynamic = lldb.eDynamicCanRunTarget no_dynamic = lldb.eNoDynamicValues myB = frame.FindVariable('myB', no_dynamic) self.assertTrue(myB) myB_loc = int(myB.GetLocation(), 16) otherB = frame.FindVariable('otherB', no_dynamic) self.assertTrue(otherB) otherB_loc = int(otherB.GetLocation(), 16) # Okay now run to doSomething: threads = lldbutil.continue_to_breakpoint(process, do_something_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "this" using FindVariable: this_static = frame.FindVariable('this', no_dynamic) this_dynamic = frame.FindVariable('this', use_dynamic) self.examine_value_object_of_this_ptr( this_static, this_dynamic, myB_loc) # Now make sure that the "GetDynamicValue" works: # This doesn't work currently because we can't get dynamic values from # ConstResult objects. fetched_dynamic_value = this_static.GetDynamicValue(use_dynamic) self.examine_value_object_of_this_ptr( this_static, fetched_dynamic_value, myB_loc) # And conversely that the GetDynamicValue() interface also works: fetched_static_value = this_dynamic.GetStaticValue() self.examine_value_object_of_this_ptr( fetched_static_value, this_dynamic, myB_loc) # Get "this" using FindValue, make sure that works too: this_static = frame.FindValue( 'this', lldb.eValueTypeVariableArgument, no_dynamic) this_dynamic = frame.FindValue( 'this', lldb.eValueTypeVariableArgument, use_dynamic) self.examine_value_object_of_this_ptr( this_static, this_dynamic, myB_loc) # Get "this" using the EvaluateExpression: this_static = frame.EvaluateExpression('this', False) this_dynamic = frame.EvaluateExpression('this', True) self.examine_value_object_of_this_ptr( this_static, this_dynamic, myB_loc) # The "frame var" code uses another path to get into children, so let's # make sure that works as well: self.expect( 'frame var -d run-target --ptr-depth=2 --show-types anotherA.m_client_A', 'frame var finds its way into a child member', patterns=['\(B \*\)']) # Now make sure we also get it right for a reference as well: anotherA_static = frame.FindVariable('anotherA', False) self.assertTrue(anotherA_static) anotherA_static_addr = int(anotherA_static.GetValue(), 16) anotherA_dynamic = frame.FindVariable('anotherA', True) self.assertTrue(anotherA_dynamic) anotherA_dynamic_addr = int(anotherA_dynamic.GetValue(), 16) anotherA_dynamic_typename = anotherA_dynamic.GetTypeName() self.assertTrue(anotherA_dynamic_typename.find('B') != -1) self.assertTrue(anotherA_dynamic_addr < anotherA_static_addr) anotherA_m_b_value_dynamic = anotherA_dynamic.GetChildMemberWithName( 'm_b_value', True) self.assertTrue(anotherA_m_b_value_dynamic) anotherA_m_b_val = int(anotherA_m_b_value_dynamic.GetValue(), 10) self.assertTrue(anotherA_m_b_val == 300) anotherA_m_b_value_static = anotherA_static.GetChildMemberWithName( 'm_b_value', True) self.assertFalse(anotherA_m_b_value_static) # Okay, now continue again, and when we hit the second breakpoint in # main threads = lldbutil.continue_to_breakpoint(process, second_call_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) reallyA_value = frame.FindVariable('reallyA', False) self.assertTrue(reallyA_value) reallyA_loc = int(reallyA_value.GetLocation(), 16) # Finally continue to doSomething again, and make sure we get the right value for anotherA, # which this time around is just an "A". threads = lldbutil.continue_to_breakpoint(process, do_something_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) anotherA_value = frame.FindVariable('anotherA', True) self.assertTrue(anotherA_value) anotherA_loc = int(anotherA_value.GetValue(), 16) self.assertTrue(anotherA_loc == reallyA_loc) self.assertTrue(anotherA_value.GetTypeName().find('B') == -1)
def test_with_python(self): """Test getting return values from stepping out.""" self.build() exe = self.getBuildArtifact("a.out") (self.target, self.process, thread, inner_sint_bkpt) = lldbutil.run_to_name_breakpoint(self, "inner_sint", exe_name = exe) error = lldb.SBError() # inner_sint returns the variable value, so capture that here: in_int = thread.GetFrameAtIndex(0).FindVariable( "value").GetValueAsSigned(error) self.assertTrue(error.Success()) thread.StepOut() self.assertTrue(self.process.GetState() == lldb.eStateStopped) self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "outer_sint") return_value = thread.GetStopReturnValue() self.assertTrue(return_value.IsValid()) ret_int = return_value.GetValueAsSigned(error) self.assertTrue(error.Success()) self.assertTrue(in_int == ret_int) # Run again and we will stop in inner_sint the second time outer_sint is called. # Then test stepping out two frames at once: thread_list = lldbutil.continue_to_breakpoint(self.process, inner_sint_bkpt) self.assertTrue(len(thread_list) == 1) thread = thread_list[0] # We are done with the inner_sint breakpoint: self.target.BreakpointDelete(inner_sint_bkpt.GetID()) frame = thread.GetFrameAtIndex(1) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "outer_sint") in_int = frame.FindVariable("value").GetValueAsSigned(error) self.assertTrue(error.Success()) thread.StepOutOfFrame(frame) self.assertTrue(self.process.GetState() == lldb.eStateStopped) self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "main") ret_value = thread.GetStopReturnValue() self.assertTrue(return_value.IsValid()) ret_int = ret_value.GetValueAsSigned(error) self.assertTrue(error.Success()) self.assertTrue(2 * in_int == ret_int) # Now try some simple returns that have different types: inner_float_bkpt = self.target.BreakpointCreateByName( "inner_float", exe) self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT) self.process.Continue() thread_list = lldbutil.get_threads_stopped_at_breakpoint( self.process, inner_float_bkpt) self.assertTrue(len(thread_list) == 1) thread = thread_list[0] self.target.BreakpointDelete(inner_float_bkpt.GetID()) frame = thread.GetFrameAtIndex(0) in_value = frame.FindVariable("value") in_float = float(in_value.GetValue()) thread.StepOut() self.assertTrue(self.process.GetState() == lldb.eStateStopped) self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "outer_float") #return_value = thread.GetStopReturnValue() #self.assertTrue(return_value.IsValid()) #return_float = float(return_value.GetValue()) #self.assertTrue(in_float == return_float) if not self.affected_by_radar_34562999(): self.return_and_test_struct_value("return_one_int") self.return_and_test_struct_value("return_two_int") self.return_and_test_struct_value("return_three_int") self.return_and_test_struct_value("return_four_int") if not self.affected_by_pr33042(): self.return_and_test_struct_value("return_five_int") self.return_and_test_struct_value("return_two_double") self.return_and_test_struct_value("return_one_double_two_float") self.return_and_test_struct_value("return_one_int_one_float_one_int") self.return_and_test_struct_value("return_one_pointer") self.return_and_test_struct_value("return_two_pointer") self.return_and_test_struct_value("return_one_float_one_pointer") self.return_and_test_struct_value("return_one_int_one_pointer") self.return_and_test_struct_value("return_three_short_one_float") self.return_and_test_struct_value("return_one_int_one_double") self.return_and_test_struct_value("return_one_int_one_double_one_int") self.return_and_test_struct_value( "return_one_short_one_double_one_short") self.return_and_test_struct_value("return_one_float_one_int_one_float") self.return_and_test_struct_value("return_two_float") # I am leaving out the packed test until we have a way to tell CLANG # about alignment when reading DWARF for packed types. #self.return_and_test_struct_value ("return_one_int_one_double_packed") self.return_and_test_struct_value("return_one_int_one_long")