def test_watch_val(self): """Exercise SBValue.Watch() API to set a watchpoint.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for read and write. value = frame0.FindValue("global", lldb.eValueTypeVariableGlobal) error = lldb.SBError() watchpoint = value.Watch(True, True, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() print watchpoint # Continue. Expect the program to stop due to the variable being written to. process.Continue() if self.TraceOn(): lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) # Continue. Expect the program to stop due to the variable being read from. process.Continue() if self.TraceOn(): lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) # Continue the process. We don't expect the program to be stopped again. process.Continue() # At this point, the inferior process should have exited. self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
def symbol_and_address_api(self): """Exercise some SBSymbol and SBAddress APIs.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create the two breakpoints inside function 'a'. breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) #print "breakpoint1:", breakpoint1 #print "breakpoint2:", breakpoint2 self.assertTrue(breakpoint1 and breakpoint1.GetNumLocations() == 1, VALID_BREAKPOINT) self.assertTrue(breakpoint2 and breakpoint2.GetNumLocations() == 1, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) # Frame #0 should be on self.line1. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread != None, "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) symbol_line1 = frame0.GetSymbol() # We should have a symbol type of code. self.assertTrue(symbol_line1.GetType() == lldb.eSymbolTypeCode) addr_line1 = symbol_line1.GetStartAddress() # And a section type of code, too. self.assertTrue( addr_line1.GetSection().GetSectionType() == lldb.eSectionTypeCode) # Continue the inferior, the breakpoint 2 should be hit. process.Continue() self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread != None, "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) symbol_line2 = frame0.GetSymbol() # We should have a symbol type of code. self.assertTrue(symbol_line2.GetType() == lldb.eSymbolTypeCode) addr_line2 = symbol_line2.GetStartAddress() # And a section type of code, too. self.assertTrue( addr_line2.GetSection().GetSectionType() == lldb.eSectionTypeCode) # Now verify that both addresses point to the same module. if self.TraceOn(): print "UUID:", addr_line1.GetModule().GetUUIDString() self.assertTrue(addr_line1.GetModule().GetUUIDString() == addr_line2.GetModule().GetUUIDString())
def test_watch_address(self): """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) value = frame0.FindValue('g_char_ptr', lldb.eValueTypeVariableGlobal) pointee = value.CreateValueFromAddress( "pointee", value.GetValueAsUnsigned(0), value.GetType().GetPointeeType()) # Watch for write to *g_char_ptr. error = lldb.SBError() watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True, error) self.assertTrue(value and watchpoint, "Successfully found the pointer and set a watchpoint") self.DebugSBValue(value) self.DebugSBValue(pointee) # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() print watchpoint # Continue. Expect the program to stop due to the variable being written to. process.Continue() if (self.TraceOn()): lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) self.DebugSBValue(pointee) self.expect(lldbutil.print_stacktrace(thread, string_buffer=True), exe=False, substrs=[self.violating_func])
def test_watchpoint_cond_api(self): """Test watchpoint condition API.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) exe = os.path.join(os.getcwd(), self.exe_name) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) error = lldb.SBError() watchpoint = value.Watch(True, False, True, error) self.assertTrue( value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) # Now set the condition as "global==5". watchpoint.SetCondition('global==5') self.expect(watchpoint.GetCondition(), exe=False, startstr='global==5') # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() print watchpoint # Continue. Expect the program to stop due to the variable being written to. process.Continue() if (self.TraceOn()): lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) # Verify that the condition is met. self.assertTrue(value.GetValueAsUnsigned() == 5)
def test_watchpoint_cond_api(self): """Test watchpoint condition API.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) exe = os.path.join(os.getcwd(), self.exe_name) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) error = lldb.SBError(); watchpoint = value.Watch(True, False, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) # Now set the condition as "global==5". watchpoint.SetCondition('global==5') self.expect(watchpoint.GetCondition(), exe=False, startstr = 'global==5') # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() print(watchpoint) # Continue. Expect the program to stop due to the variable being written to. process.Continue() if (self.TraceOn()): lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) # Verify that the condition is met. self.assertTrue(value.GetValueAsUnsigned() == 5)
def test_watch_location(self): """Exercise SBValue.WatchPointee() API to set a watchpoint.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) value = frame0.FindValue('g_char_ptr', lldb.eValueTypeVariableGlobal) pointee = value.CreateValueFromAddress("pointee", value.GetValueAsUnsigned(0), value.GetType().GetPointeeType()) # Watch for write to *g_char_ptr. error = lldb.SBError(); watchpoint = value.WatchPointee(True, False, True, error) self.assertTrue(value and watchpoint, "Successfully found the pointer and set a watchpoint") self.DebugSBValue(value) self.DebugSBValue(pointee) # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() print(watchpoint) # Continue. Expect the program to stop due to the variable being written to. process.Continue() if (self.TraceOn()): lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) self.DebugSBValue(pointee) self.expect(lldbutil.print_stacktrace(thread, string_buffer=True), exe=False, substrs = [self.violating_func])
def test(self): """Exercise some SBSymbol and SBAddress APIs.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create the two breakpoints inside function 'a'. breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) #print("breakpoint1:", breakpoint1) #print("breakpoint2:", breakpoint2) self.assertTrue(breakpoint1 and breakpoint1.GetNumLocations() == 1, VALID_BREAKPOINT) self.assertTrue(breakpoint2 and breakpoint2.GetNumLocations() == 1, 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) # Frame #0 should be on self.line1. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) symbol_line1 = frame0.GetSymbol() # We should have a symbol type of code. self.assertTrue(symbol_line1.GetType() == lldb.eSymbolTypeCode) addr_line1 = symbol_line1.GetStartAddress() # And a section type of code, too. self.assertTrue(addr_line1.GetSection().GetSectionType() == lldb.eSectionTypeCode) # Continue the inferior, the breakpoint 2 should be hit. process.Continue() self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) symbol_line2 = frame0.GetSymbol() # We should have a symbol type of code. self.assertTrue(symbol_line2.GetType() == lldb.eSymbolTypeCode) addr_line2 = symbol_line2.GetStartAddress() # And a section type of code, too. self.assertTrue(addr_line2.GetSection().GetSectionType() == lldb.eSectionTypeCode) # Now verify that both addresses point to the same module. if self.TraceOn(): print("UUID:", addr_line1.GetModule().GetUUIDString()) self.assertTrue(addr_line1.GetModule().GetUUIDString() == addr_line2.GetModule().GetUUIDString())
def struct_types(self): """Test that break on a struct declaration has no effect and test structure access for zero sized arrays.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Break on the struct declration statement in main.c. lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False) lldbutil.run_break_set_by_file_and_line (self, "main.c", self.return_line, num_expected_locations=1, loc_exact=True) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) if not process: self.fail("SBTarget.Launch() failed") thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # We should be stopped on the first executable statement within the # function where the original breakpoint was attempted. self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, substrs = ['main.c:%d' % self.first_executable_line, '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']) process.Continue() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Test zero length array access and make sure it succeeds with "frame variable" self.expect("frame variable pt.padding[0]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[0] = "]) self.expect("frame variable pt.padding[1]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[1] = "]) # Test zero length array access and make sure it succeeds with "expression" self.expect("expression -- (pt.padding[0])", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["(char)", " = "]) # The padding should be an array of size 0 self.expect("image lookup -t point_tag", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['padding[]']) # Once rdar://problem/12566646 is fixed, this should display correctly self.expect("expression -- &pt == (struct point_tag*)0", substrs = ['false'])
def struct_types(self): """Test that break on a struct declaration has no effect and test structure access for zero sized arrays.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Break on the struct declration statement in main.c. lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False) lldbutil.run_break_set_by_file_and_line (self, "main.c", self.return_line, num_expected_locations=1, loc_exact=True) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, os.getcwd()) if not process: self.fail("SBTarget.Launch() failed") thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # We should be stopped on the first executable statement within the # function where the original breakpoint was attempted. self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, substrs = ['main.c:%d' % self.first_executable_line, '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']) process.Continue() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Test zero length array access and make sure it succeeds with "frame variable" self.expect("frame variable pt.padding[0]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[0] = "]) self.expect("frame variable pt.padding[1]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[1] = "]) # Test zero length array access and make sure it succeeds with "expression" self.expect("expression -- (pt.padding[0])", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["(char)", " = "]) # The padding should be an array of size 0 self.expect("image lookup -t point_tag", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['padding[]']) # Once rdar://problem/12566646 is fixed, this should display correctly self.expect("expression -- &pt == (struct point_tag*)0", substrs = ['false'])
def step_out_of_malloc_into_function_b(self, exe_name): """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b().""" exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByName('malloc') self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) while True: thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint") caller_symbol = get_caller_symbol(thread) #print "caller symbol of malloc:", caller_symbol if not caller_symbol: self.fail("Test failed: could not locate the caller symbol of malloc") if caller_symbol == "b(int)": break #self.runCmd("thread backtrace") #self.runCmd("process status") process.Continue() thread.StepOut() self.runCmd("thread backtrace") #self.runCmd("process status") self.assertTrue(thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == self.step_out_of_malloc, "step out of malloc into function b is successful")
def test_inferior_handle_sigsegv_with_dwarf(self): self.buildDefault() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # launch process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) self.assertEqual(process.GetState(), lldb.eStateStopped) signo = process.GetUnixSignals().GetSignalNumberFromName("SIGSEGV") thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal) self.assertTrue(thread and thread.IsValid(), "Thread should be stopped due to a signal") self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.") self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo, "The stop signal was SIGSEGV") # Continue until we exit. process.Continue() self.assertEqual(process.GetState(), lldb.eStateExited) self.assertEqual(process.GetExitStatus(), 0)
def do_watchpoint_ignore_count(self): """Test SBWatchpoint.SetIgnoreCount() API.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create a breakpoint on main.c in order to set our watchpoint later. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for read and write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) watchpoint = value.Watch(True, True, True) self.assertTrue( value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() # There should be only 1 watchpoint location under the target. self.assertTrue(target.GetNumWatchpoints() == 1) watchpoint = target.GetWatchpointAtIndex(0) self.assertTrue(watchpoint.IsEnabled()) self.assertTrue(watchpoint.GetIgnoreCount() == 0) watch_id = watchpoint.GetID() self.assertTrue(watch_id != 0) print watchpoint # Now immediately set the ignore count to 2. When we continue, expect the # inferior to run to its completion without stopping due to watchpoint. watchpoint.SetIgnoreCount(2) print watchpoint process.Continue() # At this point, the inferior process should have exited. self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) # Verify some vital statistics. self.assertTrue(watchpoint) self.assertTrue(watchpoint.GetWatchSize() == 4) self.assertTrue(watchpoint.GetHitCount() == 2) print watchpoint
def frame_utils(self): exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.c", self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, os.getcwd()) if not process: self.fail("SBTarget.LaunchProcess() failed") self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) import lldbutil thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue (thread) frame0 = thread.GetFrameAtIndex(0) self.assertTrue (frame0) frame1 = thread.GetFrameAtIndex(1) self.assertTrue (frame1) parent = lldbutil.get_parent_frame(frame0) self.assertTrue(parent and parent.GetFrameID() == frame1.GetFrameID()) frame0_args = lldbutil.get_args_as_string(frame0) parent_args = lldbutil.get_args_as_string(parent) self.assertTrue(frame0_args and parent_args and "(int)val=1" in frame0_args) if self.TraceOn(): lldbutil.print_stacktrace(thread) print "Current frame: %s" % frame0_args print "Parent frame: %s" % parent_args
def do_set_watchaddress_with_invalid_watch_size(self): """Use SBTarget.WatchAddress() to set a watchpoint with invalid watch_size and verify we get a meaningful error message.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) value = frame0.FindValue('g_char_ptr', lldb.eValueTypeVariableGlobal) pointee = value.CreateValueFromAddress("pointee", value.GetValueAsUnsigned(0), value.GetType().GetPointeeType()) # Watch for write to *g_char_ptr. error = lldb.SBError(); watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 365, False, True, error) self.assertFalse(watchpoint) self.expect(error.GetCString(), exe=False, substrs = ['watch size of %d is not supported' % 365])
def expr_doesnt_deadlock(self): """Test that expr will time out and allow other threads to run if it blocks.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint at source line before call_me_to_get_lock gets called. main_file_spec = lldb.SBFileSpec("locking.c") breakpoint = target.BreakpointCreateBySourceRegex( 'Break here', main_file_spec) if self.TraceOn(): print "breakpoint:", breakpoint self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, 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) # Frame #0 should be on self.line1 and the break condition should hold. from lldbutil import get_stopped_thread thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) var = frame0.EvaluateExpression("call_me_to_get_lock()") self.assertTrue(var.IsValid()) self.assertTrue(var.GetValueAsSigned(0) == 567)
def expr_doesnt_deadlock (self): """Test that expr will time out and allow other threads to run if it blocks.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint at source line before call_me_to_get_lock gets called. main_file_spec = lldb.SBFileSpec ("locking.c") breakpoint = target.BreakpointCreateBySourceRegex('Break here', main_file_spec) if self.TraceOn(): print "breakpoint:", breakpoint self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, 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) # Frame #0 should be on self.line1 and the break condition should hold. from lldbutil import get_stopped_thread thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) var = frame0.EvaluateExpression ("call_me_to_get_lock()") self.assertTrue (var.IsValid()) self.assertTrue (var.GetValueAsSigned (0) == 567)
def get_test_frame(self, exe): # Get main source file src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "Main source file") # Get the path of the executable cwd = os.getcwd() exe_path = os.path.join(cwd, exe) # Load the executable target = self.dbg.CreateTarget(exe_path) self.assertTrue(target.IsValid(), VALID_TARGET) # Break on main function main_breakpoint = target.BreakpointCreateBySourceRegex("break here", src_file_spec) self.assertTrue(main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process args = None env = None process = target.LaunchSimple(args, env, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) # Get the thread of the process self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Get frame for current thread return thread.GetSelectedFrame()
def get_process(self): """Test Python SBThread.GetProcess() API.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.cpp", self.break_line) self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") self.runCmd("process status") proc_of_thread = thread.GetProcess() #print "proc_of_thread:", proc_of_thread self.assertTrue( proc_of_thread.GetProcessID() == process.GetProcessID())
def breakpoint_conditions_python(self): """Use Python APIs to set breakpoint conditions.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target.IsValid(), VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') #print "breakpoint:", breakpoint self.assertTrue(breakpoint.IsValid() and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # We didn't associate a thread index with the breakpoint, so it should be invalid. self.assertTrue(breakpoint.GetThreadIndex() == lldb.UINT32_MAX, "The thread index should be invalid") # The thread name should be invalid, too. self.assertTrue(breakpoint.GetThreadName() is None, "The thread name should be invalid") # Let's set the thread index for this breakpoint and verify that it is, # indeed, being set correctly. breakpoint.SetThreadIndex(1) # There's only one thread for the process. self.assertTrue(breakpoint.GetThreadIndex() == 1, "The thread index has been set correctly") # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location.IsValid() and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Set the condition on the breakpoint location. location.SetCondition('val == 3') self.expect(location.GetCondition(), exe=False, startstr = 'val == 3') # Now launch the process, and do not stop at entry point. error = lldb.SBError() self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) self.process = target.GetProcess() self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) # Frame #0 should be on self.line1 and the break condition should hold. from lldbutil import get_stopped_thread thread = get_stopped_thread(self.process, lldb.eStopReasonPlanComplete) self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) var = frame0.FindValue('val', lldb.eValueTypeVariableArgument) self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and var.GetValue(frame0) == '3') # The hit count for the breakpoint should be 3. self.assertTrue(breakpoint.GetHitCount() == 3) self.process.Continue()
def get_stop_description(self): """Test Python SBThread.GetStopDescription() API.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.cpp", self.break_line) self.assertTrue(breakpoint, VALID_BREAKPOINT) #self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") #self.runCmd("process status") # Due to the typemap magic (see lldb.swig), we pass in an (int)length to GetStopDescription # and expect to get a Python string as the return object! # The 100 is just an arbitrary number specifying the buffer size. stop_description = thread.GetStopDescription(100) self.expect(stop_description, exe=False, startstr='breakpoint')
def frame_utils(self): exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.c", self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, os.getcwd()) if not process: self.fail("SBTarget.LaunchProcess() failed") self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) import lldbutil thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) frame1 = thread.GetFrameAtIndex(1) parent = lldbutil.get_parent_frame(frame0) self.assertTrue(parent and parent.GetFrameID() == frame1.GetFrameID()) frame0_args = lldbutil.get_args_as_string(frame0) parent_args = lldbutil.get_args_as_string(parent) self.assertTrue(frame0_args and parent_args and "(int)val=1" in frame0_args) if self.TraceOn(): lldbutil.print_stacktrace(thread) print "Current frame: %s" % frame0_args print "Parent frame: %s" % parent_args
def crash_during_step_inst_test(self): exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target and target.IsValid(), "Target is valid") self.bp_num = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1) # Run the program. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) # The stop reason should be breakpoint. self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) self.assertEqual(lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint).IsValid(), 1, STOPPED_DUE_TO_BREAKPOINT) thread = process.GetThreadAtIndex(0) self.assertTrue(thread and thread.IsValid(), "Thread is valid") # Keep stepping until the inferior crashes while process.GetState() == lldb.eStateStopped and not lldbutil.is_thread_crashed(self, thread): thread.StepInstruction(False) self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) self.assertTrue(lldbutil.is_thread_crashed(self, thread), "Thread has crashed") process.Kill()
def test_ignore_signal(self): """Test Python SBUnixSignals.Suppress/Stop/Notify() API.""" self.buildDefault() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) line = line_number( "main.cpp", "// Set break point at this line and setup signal ignores.") breakpoint = target.BreakpointCreateByLocation("main.cpp", line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") unix_signals = process.GetUnixSignals() sigint = unix_signals.GetSignalNumberFromName("SIGINT") unix_signals.SetShouldSuppress(sigint, True) unix_signals.SetShouldStop(sigint, False) unix_signals.SetShouldNotify(sigint, False) process.Continue() self.assertTrue(process.state == lldb.eStateExited, "The process should have exited") self.assertTrue(process.GetExitStatus() == 0, "The process should have returned 0")
def test_set_watch_ignore_count(self): """Test SBWatchpoint.SetIgnoreCount() API.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create a breakpoint on main.c in order to set our watchpoint later. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint and breakpoint.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()) # We should be stopped due to the breakpoint. Get frame #0. process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) frame0 = thread.GetFrameAtIndex(0) # Watch 'global' for read and write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) error = lldb.SBError(); watchpoint = value.Watch(True, True, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() # There should be only 1 watchpoint location under the target. self.assertTrue(target.GetNumWatchpoints() == 1) watchpoint = target.GetWatchpointAtIndex(0) self.assertTrue(watchpoint.IsEnabled()) self.assertTrue(watchpoint.GetIgnoreCount() == 0) watch_id = watchpoint.GetID() self.assertTrue(watch_id != 0) print(watchpoint) # Now immediately set the ignore count to 2. When we continue, expect the # inferior to run to its completion without stopping due to watchpoint. watchpoint.SetIgnoreCount(2) print(watchpoint) process.Continue() # At this point, the inferior process should have exited. self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) # Verify some vital statistics. self.assertTrue(watchpoint) self.assertTrue(watchpoint.GetWatchSize() == 4) self.assertTrue(watchpoint.GetHitCount() == 2) print(watchpoint)
def test_ignore_signal(self): """Test Python SBUnixSignals.Suppress/Stop/Notify() API.""" self.buildDefault() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) line = line_number("main.cpp", "// Set break point at this line and setup signal ignores.") breakpoint = target.BreakpointCreateByLocation("main.cpp", line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") unix_signals = process.GetUnixSignals() sigint = unix_signals.GetSignalNumberFromName("SIGINT") unix_signals.SetShouldSuppress(sigint, True) unix_signals.SetShouldStop(sigint, False) unix_signals.SetShouldNotify(sigint, False) process.Continue() self.assertTrue(process.state == lldb.eStateExited, "The process should have exited") self.assertTrue(process.GetExitStatus() == 0, "The process should have returned 0")
def print_obj(self, exe_name): """ Test "print object" where another thread blocks the print object from making progress. Set a breakpoint on the line in my_pthread_routine. Then switch threads to the main thread, and do print the lock_me object. Since that will try to get the lock already gotten by my_pthread_routime thread, it will have to switch to running all threads, and that should then succeed. """ exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.runCmd("thread backtrace all") # Let's get the current stopped thread. We'd like to switch to the # other thread to issue our 'po lock_me' command. import lldbutil this_thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(this_thread) # Find the other thread. The iteration protocol of SBProcess and the # rich comparison methods (__eq__/__ne__) of SBThread come in handy. other_thread = None for t in process: if t != this_thread: other_thread = t break # Set the other thread as the selected thread to issue our 'po' command.other self.assertTrue(other_thread) process.SetSelectedThread(other_thread) if self.TraceOn(): print "selected thread:" + lldbutil.get_description(other_thread) self.runCmd("thread backtrace") # We want to traverse the frame to the one corresponding to blocked.m to # issue our 'po lock_me' command. depth = other_thread.GetNumFrames() for i in range(depth): frame = other_thread.GetFrameAtIndex(i) name = frame.GetFunctionName() if name == 'main': other_thread.SetSelectedFrame(i) if self.TraceOn(): print "selected frame:" + lldbutil.get_description(frame) break self.expect("po lock_me", OBJECT_PRINTED_CORRECTLY, substrs = ['I am pretty special.'])
def launch(self, target, signal): # launch the process, do not stop at entry point. process = target.LaunchSimple([signal], None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) self.assertEqual(process.GetState(), lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "Thread should be stopped due to a breakpoint") return process
def do_test(self): exe_name = "a.out" exe = os.path.join(os.getcwd(), exe_name) source_files = [ f for f in os.listdir(os.getcwd()) if source_type(f) ] target = self.dbg.CreateTarget(exe) parser = CommandParser() parser.parse_source_files(source_files) parser.set_breakpoints(target) process = target.LaunchSimple(None, None, os.getcwd()) while lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint): thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) breakpoint_id = thread.GetStopReasonDataAtIndex (0) parser.handle_breakpoint(self, breakpoint_id) process.Continue()
def breakpoint_conditions_python(self): """Use Python APIs to set breakpoint conditions.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') #print "breakpoint:", breakpoint self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # We didn't associate a thread index with the breakpoint, so it should be invalid. self.assertTrue(breakpoint.GetThreadIndex() == lldb.UINT32_MAX, "The thread index should be invalid") # The thread name should be invalid, too. self.assertTrue(breakpoint.GetThreadName() is None, "The thread name should be invalid") # Let's set the thread index for this breakpoint and verify that it is, # indeed, being set correctly. breakpoint.SetThreadIndex( 1) # There's only one thread for the process. self.assertTrue(breakpoint.GetThreadIndex() == 1, "The thread index has been set correctly") # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Set the condition on the breakpoint location. location.SetCondition('val == 3') self.expect(location.GetCondition(), exe=False, startstr='val == 3') # 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) # Frame #0 should be on self.line1 and the break condition should hold. from lldbutil import get_stopped_thread thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) var = frame0.FindValue('val', lldb.eValueTypeVariableArgument) self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and var.GetValue() == '3') # The hit count for the breakpoint should be 1. self.assertTrue(breakpoint.GetHitCount() == 1) process.Continue()
def do_test(self): exe_name = "a.out" exe = os.path.join(os.getcwd(), exe_name) source_files = [f for f in os.listdir(os.getcwd()) if source_type(f)] target = self.dbg.CreateTarget(exe) parser = CommandParser() parser.parse_source_files(source_files) parser.set_breakpoints(target) process = target.LaunchSimple(None, None, os.getcwd()) while lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint): thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) breakpoint_id = thread.GetStopReasonDataAtIndex(0) parser.handle_breakpoint(self, breakpoint_id) process.Continue()
def test_virtual_madness(self): """Test that expression works correctly with virtual inheritance as well as virtual function.""" self.build() # Bring the program to the point where we can issue a series of # 'expression' command to compare against the golden output. self.dbg.SetAsync(False) # Create a target by the debugger. target = self.dbg.CreateTarget("a.out") self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, 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) self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") # First, capture the golden output from the program itself from the # series of printf statements. stdout = process.GetSTDOUT(1024) # This golden list contains a list of "my_expr = 'value' pairs extracted # from the golden output. gl = [] # Scan the golden output line by line, looking for the pattern: # # my_expr = 'value' # for line in stdout.split(os.linesep): match = self.pattern.search(line) if match: my_expr, val = match.group(1), match.group(2) gl.append((my_expr, val)) #print "golden list:", gl # Now iterate through the golden list, comparing against the output from # 'expression var'. for my_expr, val in gl: self.runCmd("expression %s" % my_expr) output = self.res.GetOutput() # The expression output must match the oracle. self.expect(output, Msg(my_expr, val), exe=False, substrs=[val])
def test_with_run_command(self): self.build() # Get main source file src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "Main source file") # Get the path of the executable cwd = os.getcwd() exe_file = "a.out" exe_path = os.path.join(cwd, exe_file) # Load the executable target = self.dbg.CreateTarget(exe_path) self.assertTrue(target.IsValid(), VALID_TARGET) # Break on main function main_breakpoint = target.BreakpointCreateBySourceRegex("// break here", src_file_spec) self.assertTrue(main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process args = None env = None process = target.LaunchSimple(args, env, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) # Get the thread of the process self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Get current fream of the thread at the breakpoint frame = thread.GetSelectedFrame() # Test result for scopes of variables global_variables = frame.GetVariables(True, True, True, False) global_variables_assert = { 'A::a': 1111, 'B::a': 2222, 'C::a': 3333, '::a': 4444, 'a': 4444 } self.assertTrue(global_variables.GetSize() == 4, "target variable returns all variables") for variable in global_variables: name = variable.GetName() self.assertTrue(name in global_variables_assert, "target variable returns wrong variable " + name) for name in global_variables_assert: value = frame.EvaluateExpression(name) assert_value = global_variables_assert[name] self.assertTrue(value.IsValid() and value.GetValueAsSigned() == assert_value, name + " = " + str(assert_value))
def test_with_run_command(self): self.build() # Get main source file src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "Main source file") # Get the path of the executable cwd = os.getcwd() exe_file = "a.out" exe_path = os.path.join(cwd, exe_file) # Load the executable target = self.dbg.CreateTarget(exe_path) self.assertTrue(target.IsValid(), VALID_TARGET) # Break on main function main_breakpoint = target.BreakpointCreateBySourceRegex( "// break here", src_file_spec) self.assertTrue( main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process args = None env = None process = target.LaunchSimple(args, env, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) # Get the thread of the process self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Check if global operators are evaluated frame = thread.GetSelectedFrame() test_result = frame.EvaluateExpression("operator==(s1, s2)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "operator==(s1, s2) = false") test_result = frame.EvaluateExpression("operator==(s1, s3)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "true", "operator==(s1, s3) = true") test_result = frame.EvaluateExpression("operator==(s2, s3)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "operator==(s2, s3) = false")
def write_memory(self): """Test Python SBProcess.WriteMemory() API.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") frame = thread.GetFrameAtIndex(0) # Get the SBValue for the global variable 'my_char'. val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal) self.DebugSBValue(val) # If the variable does not have a load address, there's no sense continuing. if not val.GetLocation().startswith("0x"): return # OK, let's get the hex location of the variable. location = int(val.GetLocation(), 16) # The program logic makes the 'my_char' variable to have memory content as 'x'. # But we want to use the WriteMemory() API to assign 'a' to the variable. # Now use WriteMemory() API to write 'a' into the global variable. error = lldb.SBError() result = process.WriteMemory(location, 'a', error) if not error.Success() or result != 1: self.fail("SBProcess.WriteMemory() failed") # Read from the memory location. This time it should be 'a'. # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and # expect to get a Python string as the result object! content = process.ReadMemory(location, 1, error) if not error.Success(): self.fail("SBProcess.ReadMemory() failed") if self.TraceOn(): print "memory content:", content self.expect( content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'", exe=False, startstr='a')
def hello_watchpoint(self): """Test a simple sequence of watchpoint creation and watchpoint hit.""" exe = os.path.join(os.getcwd(), self.exe_name) self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line(self, None, self.line, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # Now let's set a write-type watchpoint for 'global'. # There should be only one watchpoint hit (see main.c). self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED, substrs=[ 'Watchpoint created', 'size = 4', 'type = w', '%s:%d' % (self.source, self.decl) ]) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should be 0 initially. self.expect("watchpoint list -v", substrs=['hit_count = 0']) self.runCmd("process continue") # We should be stopped again due to the watchpoint (write type), but # only once. The stop reason of the thread should be watchpoint. self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT, substrs=['stopped', 'stop reason = watchpoint']) self.runCmd("process continue") # Don't expect the read of 'global' to trigger a stop exception. process = self.dbg.GetSelectedTarget().GetProcess() if process.GetState() == lldb.eStateStopped: self.assertFalse( lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should now be 1. self.expect("watchpoint list -v", substrs=['hit_count = 1'])
def test_virtual_madness(self): """Test that expression works correctly with virtual inheritance as well as virtual function.""" self.build() # Bring the program to the point where we can issue a series of # 'expression' command to compare against the golden output. self.dbg.SetAsync(False) # Create a target by the debugger. target = self.dbg.CreateTarget("a.out") self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, 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) self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") # First, capture the golden output from the program itself from the # series of printf statements. stdout = process.GetSTDOUT(1024) # This golden list contains a list of "my_expr = 'value' pairs extracted # from the golden output. gl = [] # Scan the golden output line by line, looking for the pattern: # # my_expr = 'value' # for line in stdout.split(os.linesep): match = self.pattern.search(line) if match: my_expr, val = match.group(1), match.group(2) gl.append((my_expr, val)) #print("golden list:", gl) # Now iterate through the golden list, comparing against the output from # 'expression var'. for my_expr, val in gl: self.runCmd("expression %s" % my_expr) output = self.res.GetOutput() # The expression output must match the oracle. self.expect(output, Msg(my_expr, val), exe=False, substrs = [val])
def breakpoint_ignore_count_python(self): """Use Python APIs to set breakpoint ignore count.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target.IsValid(), VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') self.assertTrue(breakpoint.IsValid() and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location.IsValid() and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Set the ignore count on the breakpoint location. location.SetIgnoreCount(2) self.assertTrue(location.GetIgnoreCount() == 2, "SetIgnoreCount() works correctly") # Now launch the process, and do not stop at entry point. error = lldb.SBError() self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) self.process = target.GetProcess() self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) # Frame#0 should be on main.c:37, frame#1 should be on main.c:25, and # frame#2 should be on main.c:48. #lldbutil.PrintStackTraces(self.process) from lldbutil import get_stopped_thread thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint) self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint") frame0 = thread.GetFrameAtIndex(0) frame1 = thread.GetFrameAtIndex(1) frame2 = thread.GetFrameAtIndex(2) self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and frame1.GetLineEntry().GetLine() == self.line3 and frame2.GetLineEntry().GetLine() == self.line4, STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT) # The hit count for the breakpoint should be 3. self.assertTrue(breakpoint.GetHitCount() == 3) self.process.Continue()
def test_SBType_template_aspects(self): """Test APIs for getting template arguments from an SBType.""" self.build() exe = os.path.join(os.getcwd(), 'a.out') # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, 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) # Get Frame #0. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) # Get the type for variable 'associative_array'. associative_array = frame0.FindVariable('associative_array') self.DebugSBValue(associative_array) self.assertTrue(associative_array, VALID_VARIABLE) map_type = associative_array.GetType() self.DebugSBType(map_type) self.assertTrue(map_type, VALID_TYPE) num_template_args = map_type.GetNumberOfTemplateArguments() self.assertTrue(num_template_args > 0) # We expect the template arguments to contain at least 'string' and 'int'. expected_types = {'string': False, 'int': False} for i in range(num_template_args): t = map_type.GetTemplateArgumentType(i) self.DebugSBType(t) self.assertTrue(t, VALID_TYPE) name = t.GetName() if 'string' in name: expected_types['string'] = True elif 'int' == name: expected_types['int'] = True # Check that both entries of the dictionary have 'True' as the value. self.assertTrue(all(expected_types.values()))
def test_hello_watchpoint_using_watchpoint_set(self): """Test a simple sequence of watchpoint creation and watchpoint hit.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) exe = os.path.join(os.getcwd(), self.exe_name) self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # Now let's set a write-type watchpoint for 'global'. # There should be only one watchpoint hit (see main.c). self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED, substrs = ['Watchpoint created', 'size = 4', 'type = w', '%s:%d' % (self.source, self.decl)]) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should be 0 initially. self.expect("watchpoint list -v", substrs = ['hit_count = 0']) self.runCmd("process continue") # We should be stopped again due to the watchpoint (write type), but # only once. The stop reason of the thread should be watchpoint. self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT, substrs = ['stopped', 'stop reason = watchpoint']) self.runCmd("process continue") # Don't expect the read of 'global' to trigger a stop exception. process = self.dbg.GetSelectedTarget().GetProcess() if process.GetState() == lldb.eStateStopped: self.assertFalse(lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should now be 1. self.expect("watchpoint list -v", substrs = ['hit_count = 1'])
def test_write_memory(self): """Test Python SBProcess.WriteMemory() API.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") frame = thread.GetFrameAtIndex(0) # Get the SBValue for the global variable 'my_char'. val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal) self.DebugSBValue(val) # If the variable does not have a load address, there's no sense continuing. if not val.GetLocation().startswith("0x"): return # OK, let's get the hex location of the variable. location = int(val.GetLocation(), 16) # The program logic makes the 'my_char' variable to have memory content as 'x'. # But we want to use the WriteMemory() API to assign 'a' to the variable. # Now use WriteMemory() API to write 'a' into the global variable. error = lldb.SBError() result = process.WriteMemory(location, "a", error) if not error.Success() or result != 1: self.fail("SBProcess.WriteMemory() failed") # Read from the memory location. This time it should be 'a'. # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and # expect to get a Python string as the result object! content = process.ReadMemory(location, 1, error) if not error.Success(): self.fail("SBProcess.ReadMemory() failed") if self.TraceOn(): print("memory content:", content) self.expect( content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'", exe=False, startstr="a" )
def breakpoint_ignore_count_python(self): """Use Python APIs to set breakpoint ignore count.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Set the ignore count on the breakpoint location. location.SetIgnoreCount(2) self.assertTrue(location.GetIgnoreCount() == 2, "SetIgnoreCount() works correctly") # 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) # Frame#0 should be on main.c:37, frame#1 should be on main.c:25, and # frame#2 should be on main.c:48. #lldbutil.print_stacktraces(process) from lldbutil import get_stopped_thread thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") frame0 = thread.GetFrameAtIndex(0) frame1 = thread.GetFrameAtIndex(1) frame2 = thread.GetFrameAtIndex(2) self.assertTrue( frame0.GetLineEntry().GetLine() == self.line1 and frame1.GetLineEntry().GetLine() == self.line3 and frame2.GetLineEntry().GetLine() == self.line4, STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT) # The hit count for the breakpoint should be 3. self.assertTrue(breakpoint.GetHitCount() == 3) process.Continue()
def step_out_of_malloc_into_function_b(self, exe_name): """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b().""" exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByName('malloc') self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) while True: thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint") caller_symbol = get_caller_symbol(thread) #print "caller symbol of malloc:", caller_symbol if not caller_symbol: self.fail( "Test failed: could not locate the caller symbol of malloc" ) # Our top frame may be an inlined function in malloc() (e.g., on # FreeBSD). Apply a simple heuristic of stepping out until we find # a non-malloc caller while caller_symbol.startswith("malloc"): thread.StepOut() self.assertTrue(thread.IsValid(), "Thread valid after stepping to outer malloc") caller_symbol = get_caller_symbol(thread) if caller_symbol == "b(int)": break #self.runCmd("thread backtrace") #self.runCmd("process status") process.Continue() thread.StepOut() self.runCmd("thread backtrace") #self.runCmd("process status") self.assertTrue( thread.GetFrameAtIndex( 0).GetLineEntry().GetLine() == self.step_out_of_malloc, "step out of malloc into function b is successful")
def test_with_dwarf(self): self.buildDwarf() cwd = os.getcwd() src_file = os.path.join(cwd, "main.cpp") src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "breakpoint file") # Get the path of the executable exe_path = os.path.join(cwd, 'a.out') # Load the executable target = self.dbg.CreateTarget(exe_path) self.assertTrue(target.IsValid(), VALID_TARGET) # Break on main function breakpoint = target.BreakpointCreateBySourceRegex( "break here", src_file_spec) self.assertTrue( breakpoint.IsValid() and breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) # Get the thread of the process self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) thread.StepInto() # Get frame for current thread frame = thread.GetSelectedFrame() v1 = frame.EvaluateExpression("1") self.assertTrue(v1.IsValid(), "'expr 1' results in a valid SBValue object") self.assertTrue(v1.GetError().Success(), "'expr 1' succeeds without an error.") v2 = frame.EvaluateExpression("this") self.assertTrue(v2.IsValid(), "'expr this' results in a valid SBValue object") self.assertTrue(v2.GetError().Success(), "'expr this' succeeds without an error.")
def run_to_address(self, exe_name): """Test Python SBThread.RunToAddress() API.""" exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation('main2.cpp', self.step_out_of_malloc) self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # Frame #0 should be on self.step_out_of_malloc. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") self.runCmd("thread backtrace") frame0 = thread.GetFrameAtIndex(0) lineEntry = frame0.GetLineEntry() self.assertTrue(lineEntry.GetLine() == self.step_out_of_malloc) # Get the start/end addresses for this line entry. start_addr = lineEntry.GetStartAddress().GetLoadAddress(target) end_addr = lineEntry.GetEndAddress().GetLoadAddress(target) if self.TraceOn(): print "start addr:", hex(start_addr) print "end addr:", hex(end_addr) # Disable the breakpoint. self.assertTrue(target.DisableAllBreakpoints()) self.runCmd("breakpoint list") thread.StepOver() thread.StepOver() thread.StepOver() self.runCmd("thread backtrace") # Now ask SBThread to run to the address 'start_addr' we got earlier, which # corresponds to self.step_out_of_malloc line entry's start address. thread.RunToAddress(start_addr) self.runCmd("process status")
def test(self): """Test SBType APIs to fetch member function types.""" d = {'EXE': self.exe_name} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = os.path.join(os.getcwd(), self.exe_name) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, 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) # Get Frame #0. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) variable = frame0.FindVariable("d") Derived = variable.GetType() Base = Derived.GetDirectBaseClassAtIndex(0).GetType() self.assertTrue(Derived.GetNumberOfMemberFunctions() == 2, "Derived declares two methods") self.assertTrue(Derived.GetMemberFunctionAtIndex(0).GetType().GetFunctionReturnType().GetName() == "int", "Derived::dImpl returns int") self.assertTrue(Base.GetNumberOfMemberFunctions() == 4, "Base declares three methods") self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetType().GetFunctionArgumentTypes().GetSize() == 3, "Base::sfunc takes three arguments") self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetName() == "sfunc", "Base::sfunc not found") self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetKind() == lldb.eMemberFunctionKindStaticMethod, "Base::sfunc is a static") self.assertTrue(Base.GetMemberFunctionAtIndex(2).GetType().GetFunctionArgumentTypes().GetSize() == 0, "Base::dat takes no arguments") self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetType().GetFunctionArgumentTypes().GetTypeAtIndex(1).GetName() == "char", "Base::bar takes a second 'char' argument") self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetName() == "bar", "Base::bar not found") variable = frame0.FindVariable("thingy") Thingy = variable.GetType() self.assertTrue(Thingy.GetNumberOfMemberFunctions() == 2, "Thingy declares two methods") self.assertTrue(Thingy.GetMemberFunctionAtIndex(0).GetReturnType().GetName() == "id", "Thingy::init returns an id") self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetNumberOfArguments() == 2, "Thingy::foo takes two arguments") self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetArgumentTypeAtIndex(0).GetName() == "int", "Thingy::foo takes an int")
def test_SBType_template_aspects(self): """Test APIs for getting template arguments from an SBType.""" self.build() exe = os.path.join(os.getcwd(), 'a.out') # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, 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) # Get Frame #0. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) # Get the type for variable 'associative_array'. associative_array = frame0.FindVariable('associative_array') self.DebugSBValue(associative_array) self.assertTrue(associative_array, VALID_VARIABLE) map_type = associative_array.GetType() self.DebugSBType(map_type) self.assertTrue(map_type, VALID_TYPE) num_template_args = map_type.GetNumberOfTemplateArguments() self.assertTrue(num_template_args > 0) # We expect the template arguments to contain at least 'string' and 'int'. expected_types = { 'string': False, 'int': False } for i in range(num_template_args): t = map_type.GetTemplateArgumentType(i) self.DebugSBType(t) self.assertTrue(t, VALID_TYPE) name = t.GetName() if 'string' in name: expected_types['string'] = True elif 'int' == name: expected_types['int'] = True # Check that both entries of the dictionary have 'True' as the value. self.assertTrue(all(expected_types.values()))
def check(self): """Tests imported namespaces in C++.""" # Get main source file src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "Main source file") # Get the path of the executable cwd = os.getcwd() exe_file = "a.out" exe_path = os.path.join(cwd, exe_file) # Load the executable target = self.dbg.CreateTarget(exe_path) self.assertTrue(target.IsValid(), VALID_TARGET) # Break on main function break_0 = target.BreakpointCreateBySourceRegex("// break 0", src_file_spec) self.assertTrue(break_0.IsValid() and break_0.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process args = None env = None process = target.LaunchSimple(args, env, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) # Get the thread of the process self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Get current fream of the thread at the breakpoint frame = thread.GetSelectedFrame() # Test imported namespaces test_result = frame.EvaluateExpression("n") self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 1, "n = 1") test_result = frame.EvaluateExpression("N::n") self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 1, "N::n = 1") test_result = frame.EvaluateExpression("nested") self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 3, "nested = 3") test_result = frame.EvaluateExpression("anon") self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 2, "anon = 2")
def type_api(self, exe_name): """Test SBType APIs to fetch member function types.""" exe = os.path.join(os.getcwd(), exe_name) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, 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) # Get Frame #0. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) variable = frame0.FindVariable("d") Derived = variable.GetType() Base = Derived.GetDirectBaseClassAtIndex(0).GetType() self.assertTrue(Derived.GetNumberOfMemberFunctions() == 2, "Derived declares two methods") self.assertTrue(Derived.GetMemberFunctionAtIndex(0).GetType().GetFunctionReturnType().GetName() == "int", "Derived::dImpl returns int") self.assertTrue(Base.GetNumberOfMemberFunctions() == 4, "Base declares three methods") self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetType().GetFunctionArgumentTypes().GetSize() == 3, "Base::sfunc takes three arguments") self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetName() == "sfunc", "Base::sfunc not found") self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetKind() == lldb.eMemberFunctionKindStaticMethod, "Base::sfunc is a static") self.assertTrue(Base.GetMemberFunctionAtIndex(2).GetType().GetFunctionArgumentTypes().GetSize() == 0, "Base::dat takes no arguments") self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetType().GetFunctionArgumentTypes().GetTypeAtIndex(1).GetName() == "char", "Base::bar takes a second 'char' argument") self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetName() == "bar", "Base::bar not found") variable = frame0.FindVariable("thingy") Thingy = variable.GetType() self.assertTrue(Thingy.GetNumberOfMemberFunctions() == 2, "Thingy declares two methods") self.assertTrue(Thingy.GetMemberFunctionAtIndex(0).GetReturnType().GetName() == "id", "Thingy::init returns an id") self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetNumberOfArguments() == 2, "Thingy::foo takes two arguments") self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetArgumentTypeAtIndex(0).GetName() == "int", "Thingy::foo takes an int")
def run_to_address(self, exe_name): """Test Python SBThread.RunToAddress() API.""" exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation('main2.cpp', self.step_out_of_malloc) self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # 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 on self.step_out_of_malloc. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") self.runCmd("thread backtrace") frame0 = thread.GetFrameAtIndex(0) lineEntry = frame0.GetLineEntry() self.assertTrue(lineEntry.GetLine() == self.step_out_of_malloc) # Get the start/end addresses for this line entry. start_addr = lineEntry.GetStartAddress().GetLoadAddress(target) end_addr = lineEntry.GetEndAddress().GetLoadAddress(target) if self.TraceOn(): print "start addr:", hex(start_addr) print "end addr:", hex(end_addr) # Disable the breakpoint. self.assertTrue(target.DisableAllBreakpoints()) self.runCmd("breakpoint list") thread.StepOver() thread.StepOver() thread.StepOver() self.runCmd("thread backtrace") # Now ask SBThread to run to the address 'start_addr' we got earlier, which # corresponds to self.step_out_of_malloc line entry's start address. thread.RunToAddress(start_addr) self.runCmd("process status")
def test(self): """Test SBType for ObjC classes.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create the breakpoint inside function 'main'. breakpoint = target.BreakpointCreateByLocation("main.m", self.line) self.assertTrue(breakpoint, 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) # Get Frame #0. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") aBar = self.frame().FindVariable("aBar") aBarType = aBar.GetType() self.assertTrue(aBarType.IsValid(), "Bar should be a valid data type") self.assertTrue(aBarType.GetName() == "Bar *", "Bar has the right name") self.assertTrue(aBarType.GetNumberOfDirectBaseClasses() == 1, "Bar has a superclass") aFooType = aBarType.GetDirectBaseClassAtIndex(0) self.assertTrue(aFooType.IsValid(), "Foo should be a valid data type") self.assertTrue(aFooType.GetName() == "Foo", "Foo has the right name") self.assertTrue(aBarType.GetNumberOfFields() == 1, "Bar has a field") aBarField = aBarType.GetFieldAtIndex(0) self.assertTrue(aBarField.GetName() == "_iVar", "The field has the right name")
def step_out_of_malloc_into_function_b(self, exe_name): """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b().""" exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByName("malloc") self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) while True: thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") caller_symbol = get_caller_symbol(thread) # print "caller symbol of malloc:", caller_symbol if not caller_symbol: self.fail("Test failed: could not locate the caller symbol of malloc") # Our top frame may be an inlined function in malloc() (e.g., on # FreeBSD). Apply a simple heuristic of stepping out until we find # a non-malloc caller while caller_symbol.startswith("malloc"): thread.StepOut() self.assertTrue(thread.IsValid(), "Thread valid after stepping to outer malloc") caller_symbol = get_caller_symbol(thread) if caller_symbol == "b(int)": break # self.runCmd("thread backtrace") # self.runCmd("process status") process.Continue() thread.StepOut() self.runCmd("thread backtrace") # self.runCmd("process status") self.assertTrue( thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == self.step_out_of_malloc, "step out of malloc into function b is successful", )
def test_with_run_command(self): self.build() # Get main source file src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "Main source file") # Get the path of the executable cwd = os.getcwd() exe_file = "a.out" exe_path = os.path.join(cwd, exe_file) # Load the executable target = self.dbg.CreateTarget(exe_path) self.assertTrue(target.IsValid(), VALID_TARGET) # Break on main function main_breakpoint = target.BreakpointCreateBySourceRegex("// break here", src_file_spec) self.assertTrue(main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process args = None env = None process = target.LaunchSimple(args, env, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) # Get the thread of the process self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) # Check if global operators are evaluated frame = thread.GetSelectedFrame() test_result = frame.EvaluateExpression("operator==(s1, s2)") self.assertTrue(test_result.IsValid() and test_result.GetValue() == "false", "operator==(s1, s2) = false") test_result = frame.EvaluateExpression("operator==(s1, s3)") self.assertTrue(test_result.IsValid() and test_result.GetValue() == "true", "operator==(s1, s3) = true") test_result = frame.EvaluateExpression("operator==(s2, s3)") self.assertTrue(test_result.IsValid() and test_result.GetValue() == "false", "operator==(s2, s3) = false")
def get_process(self): """Test Python SBThread.GetProcess() API.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.cpp", self.break_line) self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint") self.runCmd("process status") proc_of_thread = thread.GetProcess() #print "proc_of_thread:", proc_of_thread self.assertTrue(proc_of_thread.GetProcessID() == process.GetProcessID())
def step_over_3_times(self, exe_name): """Test Python SBThread.StepOver() API.""" exe = os.path.join(os.getcwd(), exe_name) target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation('main2.cpp', self.step_out_of_malloc) self.assertTrue(breakpoint, VALID_BREAKPOINT) self.runCmd("breakpoint list") # 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 on self.step_out_of_malloc. self.assertTrue(process.GetState() == lldb.eStateStopped) thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") self.runCmd("thread backtrace") frame0 = thread.GetFrameAtIndex(0) lineEntry = frame0.GetLineEntry() self.assertTrue(lineEntry.GetLine() == self.step_out_of_malloc) thread.StepOver() thread.StepOver() thread.StepOver() self.runCmd("thread backtrace") # Verify that we are stopped at the correct source line number in main2.cpp. frame0 = thread.GetFrameAtIndex(0) lineEntry = frame0.GetLineEntry() self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) # Expected failure with clang as the compiler. # rdar://problem/9223880 # # Which has been fixed on the lldb by compensating for inaccurate line # table information with r140416. self.assertTrue(lineEntry.GetLine() == self.after_3_step_overs)