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 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_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(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 test_inferior_handle_sigsegv(self): 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) # 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 test_with_run_command(self): """Test that virtual base classes work in when SBValue objects are used to explore the variable value""" self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.set_breakpoint(line_number('main.cpp', '// breakpoint 1')) self.set_breakpoint(line_number('main.cpp', '// breakpoint 2')) process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) frame = thread.GetFrameAtIndex(0) j1 = frame.FindVariable("j1") j1_Derived1 = j1.GetChildAtIndex(0) j1_Derived2 = j1.GetChildAtIndex(1) j1_Derived1_VBase = j1_Derived1.GetChildAtIndex(0) j1_Derived2_VBase = j1_Derived2.GetChildAtIndex(0) j1_Derived1_VBase_m_value = j1_Derived1_VBase.GetChildAtIndex(0) j1_Derived2_VBase_m_value = j1_Derived2_VBase.GetChildAtIndex(0) self.assertTrue( j1_Derived1_VBase.GetLoadAddress() == j1_Derived2_VBase.GetLoadAddress(), "ensure virtual base class is the same between Derived1 and Derived2") self.assertTrue(j1_Derived1_VBase_m_value.GetValueAsUnsigned( 1) == j1_Derived2_VBase_m_value.GetValueAsUnsigned(2), "ensure m_value in VBase is the same") self.assertTrue(frame.FindVariable("d").GetChildAtIndex(0).GetChildAtIndex( 0).GetValueAsUnsigned(0) == 12345, "ensure Derived2 from j1 is correct") thread.StepOver() self.assertTrue(frame.FindVariable("d").GetChildAtIndex(0).GetChildAtIndex( 0).GetValueAsUnsigned(0) == 12346, "ensure Derived2 from j2 is correct")
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 = self.getBuildArtifact("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 get_stop_description(self): """Test Python SBThread.GetStopDescription() API.""" exe = self.getBuildArtifact("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 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_ignore_signal(self): """Test Python SBUnixSignals.Suppress/Stop/Notify() API.""" self.build() 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_with_run_command(self): """Test that expr will time out and allow other threads to run if it blocks.""" 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 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 lldbsuite.test.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 test_union_members(self): self._load_exe() # Set breakpoints bp = self.target.BreakpointCreateBySourceRegex( "Break here", self.src_file_spec) self.assertTrue( bp.IsValid() and bp.GetNumLocations() >= 1, VALID_BREAKPOINT) # Launch the process self.process = self.target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) self.assertTrue( self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread( self.process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid()) frame = thread.GetSelectedFrame() self.assertTrue(frame.IsValid()) val = frame.EvaluateExpression("u") self.assertTrue(val.IsValid()) val = frame.EvaluateExpression("u.s") self.assertTrue(val.IsValid()) self.assertEqual(val.GetNumChildren(), 2)
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 thread_state_after_continue_test(self): """Test thread state after continue.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint in the main thread. lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change. self.dbg.SetAsync(True) self.runCmd("continue") self.wait_for_running_event(process) # Check the thread state. It should be running. self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.") # Go back to synchronous interactions self.dbg.SetAsync(False) # Kill the process self.runCmd("process kill")
def thread_state_after_expression_test(self): """Test thread state after expression.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint in the main thread. lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Get the inferior out of its loop self.runCmd("expression g_test = 1") # Check the thread state self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.") # Let the process run to completion self.runCmd("process continue")
def test_and_python_api(self): """Use Python APIs to inspect a bitfields variable.""" self.build() 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) 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. thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # The breakpoint should have a hit count of 1. self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) # Lookup the "bits" variable which contains 8 bitfields. frame = thread.GetFrameAtIndex(0) bits = frame.FindVariable("bits") self.DebugSBValue(bits) self.assertTrue(bits.GetTypeName() == 'Bits', "bits.GetTypeName() == 'Bits'"); self.assertTrue(bits.GetNumChildren() == 10, "bits.GetNumChildren() == 10"); test_compiler = self.getCompiler() self.assertTrue(bits.GetByteSize() == 32, "bits.GetByteSize() == 32"); # Notice the pattern of int(b1.GetValue(), 0). We pass a base of 0 # so that the proper radix is determined based on the contents of the # string. b1 = bits.GetChildMemberWithName("b1") self.DebugSBValue(b1) self.assertTrue(b1.GetName() == "b1" and b1.GetTypeName() == "uint32_t:1" and b1.IsInScope() and int(b1.GetValue(), 0) == 1, 'bits.b1 has type uint32_t:1, is in scope, and == 1') b7 = bits.GetChildMemberWithName("b7") self.DebugSBValue(b7) self.assertTrue(b7.GetName() == "b7" and b7.GetTypeName() == "uint32_t:7" and b7.IsInScope() and int(b7.GetValue(), 0) == 127, 'bits.b7 has type uint32_t:7, is in scope, and == 127') four = bits.GetChildMemberWithName("four") self.DebugSBValue(four) self.assertTrue(four.GetName() == "four" and four.GetTypeName() == "uint32_t:4" and four.IsInScope() and int(four.GetValue(), 0) == 15, 'bits.four has type uint32_t:4, is in scope, and == 15') # Now kill the process, and we are done. rc = target.GetProcess().Kill() self.assertTrue(rc.Success())
def thread_state_after_breakpoint_test(self): """Test thread state after breakpoint.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint in the main thread. bp = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_1, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Make sure the thread is in the stopped state. self.assertTrue( thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.") # Kill the process self.runCmd("process kill")
def test(self): self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target and target.IsValid(), VALID_TARGET) bp = target.BreakpointCreateByName("main") self.assertTrue(bp and bp.IsValid(), "Breakpoint is valid") process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertEqual(process.GetState(), lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) frame = thread.GetFrameAtIndex(0) self.assertTrue(frame and frame.IsValid(), "Frame is valid") buf = frame.FindValue("buf", lldb.eValueTypeVariableGlobal) self.assertTrue(buf and buf.IsValid(), "buf is valid") for i in [0, target.GetAddressByteSize()]: member = buf.GetChildAtIndex(i) self.assertTrue(member and member.IsValid(), "member is valid") error = lldb.SBError() watch = member.Watch(True, True, True, error) self.assertTrue(error.Success()) process.Continue(); self.assertEqual(process.GetState(), lldb.eStateStopped) self.assertEqual(thread.GetStopReason(), lldb.eStopReasonWatchpoint)
def test_ptr_refs(self): """Test the ptr_refs tool on Darwin with Objective-C""" self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) main_file_spec = lldb.SBFileSpec('main.m') breakpoint = target.BreakpointCreateBySourceRegex( 'break', main_file_spec) self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) 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. thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame = thread.GetFrameAtIndex(0) self.dbg.HandleCommand("script import lldb.macosx.heap") self.expect("ptr_refs self", substrs=["malloc", "stack"])
def test_frame_utils(self): """Test utility functions for the frame object.""" self.build() 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, self.get_process_working_directory()) if not process: self.fail("SBTarget.LaunchProcess() failed") self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) import lldbsuite.test.lldbutil as 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 test_step_inst_with(self): """Test thread creation during step-inst handling.""" self.build(dictionary=self.getBuildFlags()) 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 prepareProcess(self): self.build() # Create a target by the debugger. exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set breakpoints inside and outside methods that take pointers to the # containing struct. line = line_number('main.cpp', '// Breakpoint 1') lldbutil.run_break_set_by_file_and_line( self, "main.cpp", line, num_expected_locations=1, loc_exact=True) arguments = None environment = None # Now launch the process, and do not stop at entry point. process = target.LaunchSimple( arguments, environment, self.get_process_working_directory()) self.assertTrue(process, 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 test_and_python_api(self): """Disassemble each call frame when stopped on C's constructor.""" self.build() self.breakOnCtor() # Now use the Python API to get at each function on the call stack and # disassemble it. target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) depth = thread.GetNumFrames() for i in range(depth - 1): frame = thread.GetFrameAtIndex(i) function = frame.GetFunction() # Print the function header. if self.TraceOn(): print() print(function) if function: # Get all instructions for this function and print them out. insts = function.GetInstructions(target) for inst in insts: # We could simply do 'print inst' to print out the disassembly. # But we want to print to stdout only if self.TraceOn() is True. disasm = str(inst) if self.TraceOn(): print(disasm)
def test_specialized_typedef_from_pch(self): self.build() 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 interesting line 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) thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") # Get frame for current thread frame = thread.frames[0] testValue = frame.EvaluateExpression("test") self.assertTrue( testValue.GetError().Success(), "Test expression value invalid: %s" % (testValue.GetError().GetCString())) self.assertTrue( testValue.GetTypeName() == "IntContainer", "Test expression type incorrect") memberValue = testValue.GetChildMemberWithName("storage") self.assertTrue( memberValue.GetError().Success(), "Member value missing or invalid: %s" % (testValue.GetError().GetCString())) self.assertTrue( memberValue.GetTypeName() == "int", "Member type incorrect") self.assertEqual( 42, memberValue.GetValueAsSigned(), "Member value incorrect")
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) target = self.dbg.CreateTarget(exe) parser = CommandParser(self) parser.parse_input() parser.set_breakpoint(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, thread, breakpoint_id) 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_with_python_api(self): """Use Python APIs to create a breakpoint by (filespec, line).""" self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) filespec = target.GetExecutable() self.assertTrue(filespec, VALID_FILESPEC) fsDir = os.path.normpath(filespec.GetDirectory()) fsFile = filespec.GetFilename() self.assertTrue(fsDir == os.path.dirname(self.getBuildArtifact()) and fsFile == "a.out", "FileSpec matches the executable") bpfilespec = lldb.SBFileSpec("main.cpp", False) breakpoint = target.BreakpointCreateByLocation(bpfilespec, self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Verify the breakpoint just created. self.expect(str(breakpoint), BREAKPOINT_CREATED, exe=False, substrs=['main.cpp', str(self.line)]) # 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") if process.GetState() != lldb.eStateStopped: self.fail("Process should be in the 'stopped' state, " "instead the actual state is: '%s'" % lldbutil.state_type_to_str(process.GetState())) # The stop reason of the thread should be breakpoint. thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # The filename of frame #0 should be 'main.cpp' and the line number # should be 93. self.expect("%s:%d" % (lldbutil.get_filenames(thread)[0], lldbutil.get_line_numbers(thread)[0]), "Break correctly at main.cpp:%d" % self.line, exe=False, startstr="main.cpp:") # clang compiled code reported main.cpp:94? # startstr = "main.cpp:93") # We should be stopped on the breakpoint with a hit count of 1. self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) process.Continue()
def test_frame_api_IsEqual(self): """Exercise SBFrame API IsEqual.""" 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 by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') #print("breakpoint:", breakpoint) 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()) process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) frameEntered = thread.GetFrameAtIndex(0) if self.TraceOn(): print(frameEntered) lldbutil.print_stacktrace(thread) self.assertTrue(frameEntered) # Doing two step overs while still inside c(). thread.StepOver() thread.StepOver() self.assertTrue(thread) frameNow = thread.GetFrameAtIndex(0) if self.TraceOn(): print(frameNow) lldbutil.print_stacktrace(thread) self.assertTrue(frameNow) # The latest two frames are considered equal. self.assertTrue(frameEntered.IsEqual(frameNow)) # Now let's step out of frame c(). thread.StepOutOfFrame(frameNow) frameOutOfC = thread.GetFrameAtIndex(0) if self.TraceOn(): print(frameOutOfC) lldbutil.print_stacktrace(thread) self.assertTrue(frameOutOfC) # The latest two frames should not be equal. self.assertFalse(frameOutOfC.IsEqual(frameNow))
def test_and_python_api(self): """Use Python APIs to inspect a bitfields variable.""" self.build() 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) 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. thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # The breakpoint should have a hit count of 1. self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) # Lookup the "bits" variable which contains 8 bitfields. frame = thread.GetFrameAtIndex(0) bits = frame.FindVariable("bits") self.DebugSBValue(bits) self.assertTrue(bits.GetTypeName() == 'Bits', "bits.GetTypeName() == 'Bits'") self.assertTrue(bits.GetNumChildren() == 10, "bits.GetNumChildren() == 10") test_compiler = self.getCompiler() self.assertTrue(bits.GetByteSize() == 32, "bits.GetByteSize() == 32") # Notice the pattern of int(b1.GetValue(), 0). We pass a base of 0 # so that the proper radix is determined based on the contents of the # string. b1 = bits.GetChildMemberWithName("b1") self.DebugSBValue(b1) self.assertTrue( b1.GetName() == "b1" and b1.GetTypeName() == "uint32_t:1" and b1.IsInScope() and int(b1.GetValue(), 0) == 1, 'bits.b1 has type uint32_t:1, is in scope, and == 1') b7 = bits.GetChildMemberWithName("b7") self.DebugSBValue(b7) self.assertTrue( b7.GetName() == "b7" and b7.GetTypeName() == "uint32_t:7" and b7.IsInScope() and int(b7.GetValue(), 0) == 127, 'bits.b7 has type uint32_t:7, is in scope, and == 127') four = bits.GetChildMemberWithName("four") self.DebugSBValue(four) self.assertTrue( four.GetName() == "four" and four.GetTypeName() == "uint32_t:4" and four.IsInScope() and int(four.GetValue(), 0) == 15, 'bits.four has type uint32_t:4, is in scope, and == 15') # Now kill the process, and we are done. rc = target.GetProcess().Kill() self.assertTrue(rc.Success())
def test_read_memory(self): """Test Python SBProcess.ReadMemory() API.""" self.build() exe = self.getBuildArtifact("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) # 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! error = lldb.SBError() self.assertFalse(val.TypeIsPointerType()) content = process.ReadMemory(val.AddressOf().GetValueAsUnsigned(), 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: 'x'", exe=False, startstr=b'x') # Read (char *)my_char_ptr. val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal) self.DebugSBValue(val) cstring = process.ReadCStringFromMemory(val.GetValueAsUnsigned(), 256, error) if not error.Success(): self.fail("SBProcess.ReadCStringFromMemory() failed") if self.TraceOn(): print("cstring read is:", cstring) self.expect( cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output", exe=False, startstr='Does it work?') # Get the SBValue for the global variable 'my_cstring'. val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal) self.DebugSBValue(val) # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes # from the address, and expect to get a Python string as the result # object! self.assertFalse(val.TypeIsPointerType()) cstring = process.ReadCStringFromMemory( val.AddressOf().GetValueAsUnsigned(), 256, error) if not error.Success(): self.fail("SBProcess.ReadCStringFromMemory() failed") if self.TraceOn(): print("cstring read is:", cstring) self.expect( cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output", exe=False, startstr='lldb.SBProcess.ReadCStringFromMemory() works!') # Get the SBValue for the global variable 'my_uint32'. val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal) self.DebugSBValue(val) # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes # from the address, and expect to get an int as the result! self.assertFalse(val.TypeIsPointerType()) my_uint32 = process.ReadUnsignedFromMemory( val.AddressOf().GetValueAsUnsigned(), 4, error) if not error.Success(): self.fail("SBProcess.ReadCStringFromMemory() failed") if self.TraceOn(): print("uint32 read is:", my_uint32) if my_uint32 != 12345: self.fail( "Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output" )
def thread_states_test(self): """Test thread states (comprehensive).""" exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint in the main thread. lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.break_1, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.break_2, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Make sure the thread is in the stopped state. self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.") # Continue, the inferior will go into an infinite loop waiting for # 'g_test' to change. self.dbg.SetAsync(True) self.runCmd("continue") self.wait_for_running_event(process) # Check the thread state. It should be running. self.assertFalse( thread.IsStopped(), "Thread state is \'stopped\' when it should be running.") self.assertFalse( thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.") # Go back to synchronous interactions self.dbg.SetAsync(False) # Stop the process self.runCmd("process interrupt") self.assertEqual(thread.GetState(), lldb.eStopReasonSignal) # Check the thread state self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after process stop.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after process stop.") # Get the inferior out of its loop self.runCmd("expression g_test = 1") # Check the thread state self.assertTrue( thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.") self.assertFalse( thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.") self.assertEqual(thread.GetState(), lldb.eStopReasonSignal) # Run to breakpoint 2 self.runCmd("continue") self.assertEqual(thread.GetState(), lldb.eStopReasonBreakpoint) # Make sure both threads are stopped self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 2.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 2.") # Run to completion self.runCmd("continue") # At this point, the inferior process should have exited. self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
def resolve_symbol_context_with_address(self): """Exercise SBTarget.ResolveSymbolContextForAddress() API.""" exe = self.getBuildArtifact("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) self.trace("breakpoint1:", breakpoint1) self.trace("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.assertEqual(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") #self.runCmd("process status") frame0 = thread.GetFrameAtIndex(0) lineEntry = frame0.GetLineEntry() self.assertEqual(lineEntry.GetLine(), self.line1) address1 = lineEntry.GetStartAddress() # Continue the inferior, the breakpoint 2 should be hit. process.Continue() self.assertEqual(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") #self.runCmd("process status") frame0 = thread.GetFrameAtIndex(0) lineEntry = frame0.GetLineEntry() self.assertEqual(lineEntry.GetLine(), self.line2) address2 = lineEntry.GetStartAddress() self.trace("address1:", address1) self.trace("address2:", address2) # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses # from our line entry. context1 = target.ResolveSymbolContextForAddress( address1, lldb.eSymbolContextEverything) context2 = target.ResolveSymbolContextForAddress( address2, lldb.eSymbolContextEverything) self.assertTrue(context1 and context2) self.trace("context1:", context1) self.trace("context2:", context2) # Verify that the context point to the same function 'a'. symbol1 = context1.GetSymbol() symbol2 = context2.GetSymbol() self.assertTrue(symbol1 and symbol2) self.trace("symbol1:", symbol1) self.trace("symbol2:", symbol2) from lldbsuite.test.lldbutil import get_description desc1 = get_description(symbol1) desc2 = get_description(symbol2) self.assertTrue(desc1 and desc2 and desc1 == desc2, "The two addresses should resolve to the same symbol")
def test_print_obj(self): """ 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. """ d = {'EXE': 'b.out'} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = self.getBuildArtifact('b.out') 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 lldbsuite.test.lldbutil as 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 test_stdcxx_disasm(self): """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib.""" self.build() (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "// Set break point at this line", lldb.SBFileSpec("main.cpp")) # Disassemble the functions on the call stack. self.runCmd("thread backtrace") thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) depth = thread.GetNumFrames() for i in range(depth - 1): frame = thread.GetFrameAtIndex(i) function = frame.GetFunction() if function.GetName(): self.runCmd("disassemble -n '%s'" % function.GetName()) lib_stdcxx = "FAILHORRIBLYHERE" # Iterate through the available modules, looking for stdc++ library... for i in range(target.GetNumModules()): module = target.GetModuleAtIndex(i) fs = module.GetFileSpec() if (fs.GetFilename().startswith("libstdc++") or fs.GetFilename().startswith("libc++")): lib_stdcxx = str(fs) break # At this point, lib_stdcxx is the full path to the stdc++ library and # module is the corresponding SBModule. self.expect(lib_stdcxx, "Libraray StdC++ is located", exe=False, substrs=["lib"]) self.runCmd("image dump symtab '%s'" % lib_stdcxx) raw_output = self.res.GetOutput() # Now, look for every 'Code' symbol and feed its load address into the # command: 'disassemble -s load_address -e end_address', where the # end_address is taken from the next consecutive 'Code' symbol entry's # load address. # # The load address column comes after the file address column, with both # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. codeRE = re.compile(r""" \ Code\ {9} # ' Code' followed by 9 SPCs, 0x[0-9a-f]{16} # the file address column, and \ # a SPC, and (0x[0-9a-f]{16}) # the load address column, and .* # the rest. """, re.VERBOSE) # Maintain a start address variable; if we arrive at a consecutive Code # entry, then the load address of the that entry is fed as the end # address to the 'disassemble -s SA -e LA' command. SA = None for line in raw_output.split(os.linesep): match = codeRE.search(line) if match: LA = match.group(1) if self.TraceOn(): print("line:", line) print("load address:", LA) print("SA:", SA) if SA and LA: if int(LA, 16) > int(SA, 16): self.runCmd("disassemble -s %s -e %s" % (SA, LA)) SA = LA else: # This entry is not a Code entry. Reset SA = None. SA = None
def test_get_arg_vals_for_call_stack(self): """Exercise SBFrame.GetVariables() API to get argument vals.""" 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 by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') #print("breakpoint:", breakpoint) 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()) process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) # Keeps track of the number of times 'a' is called where it is within a # depth of 3 of the 'c' leaf function. callsOfA = 0 from six import StringIO as SixStringIO session = SixStringIO() while process.GetState() == lldb.eStateStopped: thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Inspect at most 3 frames. numFrames = min(3, thread.GetNumFrames()) for i in range(numFrames): frame = thread.GetFrameAtIndex(i) if self.TraceOn(): print("frame:", frame) name = frame.GetFunction().GetName() if name == 'a': callsOfA = callsOfA + 1 # We'll inspect only the arguments for the current frame: # # arguments => True # locals => False # statics => False # in_scope_only => True valList = frame.GetVariables(True, False, False, True) argList = [] for val in valList: argList.append( "(%s)%s=%s" % (val.GetTypeName(), val.GetName(), val.GetValue())) print("%s(%s)" % (name, ", ".join(argList)), file=session) # Also check the generic pc & stack pointer. We can't test their absolute values, # but they should be valid. Uses get_GPRs() from the lldbutil module. gpr_reg_set = lldbutil.get_GPRs(frame) pc_value = gpr_reg_set.GetChildMemberWithName("pc") self.assertTrue(pc_value, "We should have a valid PC.") pc_value_int = int(pc_value.GetValue(), 0) # Make sure on arm targets we dont mismatch PC value on the basis of thumb bit. # Frame PC will not have thumb bit set in case of a thumb instruction as PC. if self.getArchitecture() in ['arm']: pc_value_int &= ~1 self.assertTrue( pc_value_int == frame.GetPC(), "PC gotten as a value should equal frame's GetPC") sp_value = gpr_reg_set.GetChildMemberWithName("sp") self.assertTrue(sp_value, "We should have a valid Stack Pointer.") self.assertTrue( int(sp_value.GetValue(), 0) == frame.GetSP(), "SP gotten as a value should equal frame's GetSP") print("---", file=session) process.Continue() # At this point, the inferior process should have exited. self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) # Expect to find 'a' on the call stacks two times. self.assertTrue(callsOfA == 2, "Expect to find 'a' on the call stacks two times") # By design, the 'a' call frame has the following arg vals: # o a((int)val=1, (char)ch='A') # o a((int)val=3, (char)ch='A') if self.TraceOn(): print("Full stack traces when stopped on the breakpoint 'c':") print(session.getvalue()) self.expect(session.getvalue(), "Argugment values displayed correctly", exe=False, substrs=[ "a((int)val=1, (char)ch='A')", "a((int)val=3, (char)ch='A')" ])
def test_with_python(self): """Test getting return values from stepping out.""" self.build() exe = os.path.join(os.getcwd(), "a.out") error = lldb.SBError() self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) inner_sint_bkpt = self.target.BreakpointCreateByName("inner_sint", exe) self.assertTrue(inner_sint_bkpt, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = self.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. self.assertTrue(self.process.GetState() == lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT) # Now finish, and make sure the return value is correct. thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint) # 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: self.process.Continue() thread_list = lldbutil.get_threads_stopped_at_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) 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") 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") # icc and gcc don't support this extension. if self.getCompiler().endswith('clang'): self.return_and_test_struct_value("return_vector_size_float32_8") self.return_and_test_struct_value("return_vector_size_float32_16") self.return_and_test_struct_value("return_vector_size_float32_32") self.return_and_test_struct_value( "return_ext_vector_size_float32_2") self.return_and_test_struct_value( "return_ext_vector_size_float32_4") self.return_and_test_struct_value( "return_ext_vector_size_float32_8")
def test_with_run_command(self): """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process.""" self.build() exe = self.getBuildArtifact("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.BreakpointCreateByLocation('main.c', self.line) 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) # Now launch the process, no arguments & do not stop at entry point. launch_info = target.GetLaunchInfo() launch_info.SetWorkingDirectory(self.get_process_working_directory()) process_listener = lldb.SBListener("signal_test_listener") launch_info.SetListener(process_listener) error = lldb.SBError() process = target.Launch(launch_info, error) self.assertTrue(process, PROCESS_IS_VALID) self.runCmd("process handle -n False -p True -s True SIGUSR1") thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "We hit the first breakpoint.") # After resuming the process, send it a SIGUSR1 signal. self.setAsync(True) self.assertTrue( process_listener.IsValid(), "Got a good process listener") # Disable our breakpoint, we don't want to hit it anymore... breakpoint.SetEnabled(False) # Now continue: process.Continue() # If running remote test, there should be a connected event if lldb.remote_platform: self.match_state(process_listener, lldb.eStateConnected) self.match_state(process_listener, lldb.eStateRunning) # Now signal the process, and make sure it stops: process.Signal(lldbutil.get_signal_number('SIGUSR1')) self.match_state(process_listener, lldb.eStateStopped) # Now make sure the thread was stopped with a SIGUSR1: threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonSignal) self.assertEquals(len(threads), 1, "One thread stopped for a signal.") thread = threads[0] self.assertTrue( thread.GetStopReasonDataCount() >= 1, "There was data in the event.") self.assertTrue( thread.GetStopReasonDataAtIndex(0) == lldbutil.get_signal_number('SIGUSR1'), "The stop signal was SIGUSR1")
def do_test(self, test_c): 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: if name is "C::a" and not test_c: continue if name is not "C::a" and test_c: continue 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(self): """Exercise SBSymbolContext API extensively.""" self.build() exe = self.getBuildArtifact("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', exe) 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.line. thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") frame0 = thread.GetFrameAtIndex(0) self.assertEqual(frame0.GetLineEntry().GetLine(), self.line) # Now get the SBSymbolContext from this frame. We want everything. :-) context = frame0.GetSymbolContext(lldb.eSymbolContextEverything) self.assertTrue(context) # Get the description of this module. module = context.GetModule() desc = lldbutil.get_description(module) self.expect(desc, "The module should match", exe=False, substrs=[exe]) compileUnit = context.GetCompileUnit() self.expect(str(compileUnit), "The compile unit should match", exe=False, substrs=[self.getSourcePath('main.c')]) function = context.GetFunction() self.assertTrue(function) block = context.GetBlock() self.assertTrue(block) lineEntry = context.GetLineEntry() self.expect(lineEntry.GetFileSpec().GetDirectory(), "The line entry should have the correct directory", exe=False, substrs=[self.mydir]) self.expect(lineEntry.GetFileSpec().GetFilename(), "The line entry should have the correct filename", exe=False, substrs=['main.c']) self.assertEqual(lineEntry.GetLine(), self.line, "The line entry's line number should match ") symbol = context.GetSymbol() self.assertTrue( function.GetName() == symbol.GetName() and symbol.GetName() == 'c', "The symbol name should be 'c'") sc_list = lldb.SBSymbolContextList() sc_list.Append(context) self.assertEqual(len(sc_list), 1) for sc in sc_list: self.assertEqual(lineEntry, sc.GetLineEntry())
def test_watch_location(self): """Exercise SBValue.WatchPointee() API to set a watchpoint.""" self.build() exe = self.getBuildArtifact("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.assertEqual(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_change_value(self): """Exercise the SBValue::SetValueFromCString API.""" d = {'EXE': self.exe_name} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = self.getBuildArtifact(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('main.c', self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Create the breakpoint inside the function 'main' check_breakpoint = target.BreakpointCreateByLocation( 'main.c', self.check_line) self.assertTrue(check_breakpoint, VALID_BREAKPOINT) # Create the breakpoint inside function 'main'. end_breakpoint = target.BreakpointCreateByLocation( 'main.c', self.end_line) self.assertTrue(end_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.assertEquals(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) self.assertTrue(frame0.IsValid(), "Got a valid frame.") # Get the val variable and change it: error = lldb.SBError() val_value = frame0.FindVariable("val") self.assertTrue(val_value.IsValid(), "Got the SBValue for val") actual_value = val_value.GetValueAsSigned(error, 0) self.assertTrue(error.Success(), "Got a value from val") self.assertEquals(actual_value, 100, "Got the right value from val") result = val_value.SetValueFromCString("12345") self.assertTrue(result, "Setting val returned True.") actual_value = val_value.GetValueAsSigned(error, 0) self.assertTrue(error.Success(), "Got a changed value from val") self.assertEqual(actual_value, 12345, "Got the right changed value from val") # Now check that we can set a structure element: mine_value = frame0.FindVariable("mine") self.assertTrue(mine_value.IsValid(), "Got the SBValue for mine") mine_second_value = mine_value.GetChildMemberWithName("second_val") self.assertTrue(mine_second_value.IsValid(), "Got second_val from mine") actual_value = mine_second_value.GetValueAsUnsigned(error, 0) self.assertTrue(error.Success(), "Got an unsigned value for second_val") self.assertEquals(actual_value, 5555) result = mine_second_value.SetValueFromCString("98765") self.assertTrue(result, "Success setting mine.second_value.") actual_value = mine_second_value.GetValueAsSigned(error, 0) self.assertTrue(error.Success(), "Got a changed value from mine.second_val") self.assertEquals(actual_value, 98765, "Got the right changed value from mine.second_val") # Next do the same thing with the pointer version. ptr_value = frame0.FindVariable("ptr") self.assertTrue(ptr_value.IsValid(), "Got the SBValue for ptr") ptr_second_value = ptr_value.GetChildMemberWithName("second_val") self.assertTrue(ptr_second_value.IsValid(), "Got second_val from ptr") actual_value = ptr_second_value.GetValueAsUnsigned(error, 0) self.assertTrue(error.Success(), "Got an unsigned value for ptr->second_val") self.assertEquals(actual_value, 6666) result = ptr_second_value.SetValueFromCString("98765") self.assertTrue(result, "Success setting ptr->second_value.") actual_value = ptr_second_value.GetValueAsSigned(error, 0) self.assertTrue(error.Success(), "Got a changed value from ptr->second_val") self.assertEquals(actual_value, 98765, "Got the right changed value from ptr->second_val") # gcc may set multiple locations for breakpoint breakpoint.SetEnabled(False) # Now continue. process.Continue() self.assertEquals(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") # Grab the stdout and make sure we changed the real values as well. # This doesn't work for reproducers as the inferior doesn't run. if not configuration.is_reproducer(): expected_value = "Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666" stdout = process.GetSTDOUT(1000) self.assertTrue(expected_value in stdout, "STDOUT showed changed values.") # Finally, change the stack pointer to 0, and we should not make it to # our end breakpoint. frame0 = thread.GetFrameAtIndex(0) self.assertTrue(frame0.IsValid(), "Second time: got a valid frame.") sp_value = frame0.FindValue("sp", lldb.eValueTypeRegister) self.assertTrue(sp_value.IsValid(), "Got a stack pointer value") result = sp_value.SetValueFromCString("1") self.assertTrue(result, "Setting sp returned true.") actual_value = sp_value.GetValueAsUnsigned(error, 0) self.assertTrue(error.Success(), "Got a changed value for sp") self.assertEqual(actual_value, 1, "Got the right changed value for sp.") # Boundary condition test the SBValue.CreateValueFromExpression() API. # LLDB should not crash! nosuchval = mine_value.CreateValueFromExpression(None, None) process.Continue() self.assertEquals(process.GetState(), lldb.eStateStopped) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread is None, "We should not have managed to hit our second breakpoint with sp == 1" ) process.Kill()
def test(self): """Exercise SBValue API linked_list_iter.""" d = {'EXE': self.exe_name} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = self.getBuildArtifact(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('main.cpp', 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.assertEqual(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 variable 'task_head'. task_head = frame0.FindVariable('task_head') self.assertTrue(task_head, VALID_VARIABLE) self.DebugSBValue(task_head) # By design (see main.cpp), the visited id's are: [1, 2, 4, 5]. visitedIDs = [1, 2, 4, 5] list = [] cvf = lldbutil.ChildVisitingFormatter(indent_child=2) for t in task_head.linked_list_iter('next'): self.assertTrue(t, VALID_VARIABLE) # Make sure that 'next' corresponds to an SBValue with pointer # type. self.assertTrue(t.TypeIsPointerType()) if self.TraceOn(): print(cvf.format(t)) list.append(int(t.GetChildMemberWithName("id").GetValue())) # Sanity checks that the we visited all the items (no more, no less). if self.TraceOn(): print("visited IDs:", list) self.assertEqual(visitedIDs, list) # Let's exercise the linked_list_iter() API again, this time supplying # our end of list test function. def eol(val): """Test function to determine end of list.""" # End of list is reached if either the value object is invalid # or it corresponds to a null pointer. if not val or int(val.GetValue(), 16) == 0: return True # Also check the "id" for correct semantics. If id <= 0, the item # is corrupted, let's return True to signify end of list. if int(val.GetChildMemberWithName("id").GetValue(), 0) <= 0: return True # Otherwise, return False. return False list = [] for t in task_head.linked_list_iter('next', eol): self.assertTrue(t, VALID_VARIABLE) # Make sure that 'next' corresponds to an SBValue with pointer # type. self.assertTrue(t.TypeIsPointerType()) if self.TraceOn(): print(cvf.format(t)) list.append(int(t.GetChildMemberWithName("id").GetValue())) # Sanity checks that the we visited all the items (no more, no less). if self.TraceOn(): print("visited IDs:", list) self.assertEqual(visitedIDs, list) # Get variable 'empty_task_head'. empty_task_head = frame0.FindVariable('empty_task_head') self.assertTrue(empty_task_head, VALID_VARIABLE) self.DebugSBValue(empty_task_head) list = [] # There is no iterable item from empty_task_head.linked_list_iter(). for t in empty_task_head.linked_list_iter('next', eol): if self.TraceOn(): print(cvf.format(t)) list.append(int(t.GetChildMemberWithName("id").GetValue())) self.assertEqual(len(list), 0) # Get variable 'task_evil'. task_evil = frame0.FindVariable('task_evil') self.assertTrue(task_evil, VALID_VARIABLE) self.DebugSBValue(task_evil) list = [] # There 3 iterable items from task_evil.linked_list_iter(). :-) for t in task_evil.linked_list_iter('next'): if self.TraceOn(): print(cvf.format(t)) list.append(int(t.GetChildMemberWithName("id").GetValue())) self.assertEqual(len(list), 3)
def test_unwind_signal(self): """Inferior calls sigill() and handles the resultant SIGILL. Stopped at a breakpoint in the handler, check that we can unwind back to sigill() and get the expected register contents there.""" self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) self.assertState(process.GetState(), lldb.eStateStopped) signo = process.GetUnixSignals().GetSignalNumberFromName("SIGILL") 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 should be data in the event.") self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo, "The stop signal should be SIGILL") # Continue to breakpoint in sigill handler bkpt = target.FindBreakpointByID( lldbutil.run_break_set_by_source_regexp(self, "Set a breakpoint here")) threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Expected single thread") thread = threads[0] # Expect breakpoint in 'handler' frame = thread.GetFrameAtIndex(0) self.assertEqual(frame.GetDisplayFunctionName(), "handler", "Unexpected break?") # Expect that unwinding should find 'sigill' found_caller = False for frame in thread.get_thread_frames(): if frame.GetDisplayFunctionName() == "sigill": # We should have ascending values in the x registers regs = frame.GetRegisters().GetValueAtIndex(0) err = lldb.SBError() for i in range(31): name = 'x{}'.format(i) value = regs.GetChildMemberWithName(name).GetValueAsUnsigned(err) self.assertSuccess(err, "Failed to get register {}".format(name)) self.assertEqual(value, i, "Unexpected value for register {}".format( name)) found_caller = True break self.assertTrue(found_caller, "Unwinding did not find func that caused the SIGILL") # Continue until we exit. process.Continue() self.assertState(process.GetState(), lldb.eStateExited) self.assertEqual(process.GetExitStatus(), 0)
def test_with_run_command(self): """Tests imported namespaces in C++.""" self.build() # Get main source file src_file = os.path.join(self.getSourceDir(), "main.cpp") src_file_spec = lldb.SBFileSpec(src_file) self.assertTrue(src_file_spec.IsValid(), "Main source file") # Get the path of the executable exe_path = self.getBuildArtifact("a.out") # 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) break_1 = target.BreakpointCreateBySourceRegex("// break 1", src_file_spec) self.assertTrue(break_1.IsValid() and break_1.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") test_result = frame.EvaluateExpression("global") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 4, "global = 4") test_result = frame.EvaluateExpression("fun_var") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 9, "fun_var = 9") test_result = frame.EvaluateExpression("Fun::fun_var") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 0, "Fun::fun_var = 0") test_result = frame.EvaluateExpression("not_imported") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 35, "not_imported = 35") # Currently there is no way to distinguish between "::imported" and "imported" in ClangExpressionDeclMap so this fails #test_result = frame.EvaluateExpression("::imported") #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 89, "::imported = 89") test_result = frame.EvaluateExpression("Imported::imported") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 99, "Imported::imported = 99") test_result = frame.EvaluateExpression("imported") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 99, "imported = 99") test_result = frame.EvaluateExpression("single") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 3, "single = 3") # Continue to second breakpoint process.Continue() # 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 function inside namespace test_result = frame.EvaluateExpression("fun_var") self.assertTrue( test_result.IsValid() and test_result.GetValueAsSigned() == 5, "fun_var = 5")
def test(self): """Exercise some SBValue APIs.""" d = {'EXE': self.exe_name} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = self.getBuildArtifact(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('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, 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 global variable 'days_of_week'. list = target.FindGlobalVariables('days_of_week', 1) days_of_week = list.GetValueAtIndex(0) self.assertTrue(days_of_week, VALID_VARIABLE) self.assertEqual(days_of_week.GetNumChildren(), 7, VALID_VARIABLE) self.DebugSBValue(days_of_week) # Use this to test the "child" and "children" accessors: children = days_of_week.children self.assertEqual(len(children), 7, VALID_VARIABLE) for i in range(0, len(children)): day = days_of_week.child[i] list_day = children[i] self.assertNotEqual(day, None) self.assertNotEqual(list_day, None) self.assertEqual(day.GetSummary(), list_day.GetSummary(), VALID_VARIABLE) # Spot check the actual value: first_day = days_of_week.child[1] self.assertEqual(first_day.GetSummary(), '"Monday"', VALID_VARIABLE) # Get global variable 'weekdays'. list = target.FindGlobalVariables('weekdays', 1) weekdays = list.GetValueAtIndex(0) self.assertTrue(weekdays, VALID_VARIABLE) self.assertTrue(weekdays.GetNumChildren() == 5, VALID_VARIABLE) self.DebugSBValue(weekdays) # Get global variable 'g_table'. list = target.FindGlobalVariables('g_table', 1) g_table = list.GetValueAtIndex(0) self.assertTrue(g_table, VALID_VARIABLE) self.assertTrue(g_table.GetNumChildren() == 2, VALID_VARIABLE) self.DebugSBValue(g_table) fmt = lldbutil.BasicFormatter() cvf = lldbutil.ChildVisitingFormatter(indent_child=2) rdf = lldbutil.RecursiveDecentFormatter(indent_child=2) if self.TraceOn(): print(fmt.format(days_of_week)) print(cvf.format(days_of_week)) print(cvf.format(weekdays)) print(rdf.format(g_table)) # Get variable 'my_int_ptr'. value = frame0.FindVariable('my_int_ptr') self.assertTrue(value, VALID_VARIABLE) self.DebugSBValue(value) # Get what 'my_int_ptr' points to. pointed = value.GetChildAtIndex(0) self.assertTrue(pointed, VALID_VARIABLE) self.DebugSBValue(pointed) # While we are at it, verify that 'my_int_ptr' points to 'g_my_int'. symbol = target.ResolveLoadAddress(int(pointed.GetLocation(), 0)).GetSymbol() self.assertTrue(symbol) self.expect(symbol.GetName(), exe=False, startstr='g_my_int') # Get variable 'str_ptr'. value = frame0.FindVariable('str_ptr') self.assertTrue(value, VALID_VARIABLE) self.DebugSBValue(value) # SBValue::TypeIsPointerType() should return true. self.assertTrue(value.TypeIsPointerType()) # Verify the SBValue::GetByteSize() API is working correctly. arch = self.getArchitecture() if arch == 'i386': self.assertTrue(value.GetByteSize() == 4) elif arch == 'x86_64': self.assertTrue(value.GetByteSize() == 8) # Get child at index 5 => 'Friday'. child = value.GetChildAtIndex(5, lldb.eNoDynamicValues, True) self.assertTrue(child, VALID_VARIABLE) self.DebugSBValue(child) self.expect(child.GetSummary(), exe=False, substrs=['Friday']) # Now try to get at the same variable using GetValueForExpressionPath(). # These two SBValue objects should have the same value. val2 = value.GetValueForExpressionPath('[5]') self.assertTrue(val2, VALID_VARIABLE) self.DebugSBValue(val2) self.assertTrue(child.GetValue() == val2.GetValue() and child.GetSummary() == val2.GetSummary()) val_i = target.EvaluateExpression('i') val_s = target.EvaluateExpression('s') val_a = target.EvaluateExpression('a') self.assertTrue( val_s.GetChildMemberWithName('a').GetAddress().IsValid(), VALID_VARIABLE) self.assertTrue( val_s.GetChildMemberWithName('a').AddressOf(), VALID_VARIABLE) self.assertTrue( val_a.Cast(val_i.GetType()).AddressOf(), VALID_VARIABLE) # Check that lldb.value implements truth testing. self.assertFalse(lldb.value(frame0.FindVariable('bogus'))) self.assertTrue(lldb.value(frame0.FindVariable('uinthex'))) self.assertTrue( int(lldb.value(frame0.FindVariable('uinthex'))) == 3768803088, 'uinthex == 3768803088') self.assertTrue( int(lldb.value(frame0.FindVariable('sinthex'))) == -526164208, 'sinthex == -526164208') # Check value_iter works correctly. for v in [ lldb.value(frame0.FindVariable('uinthex')), lldb.value(frame0.FindVariable('sinthex')) ]: self.assertTrue(v) self.assertTrue( frame0.FindVariable('uinthex').GetValueAsUnsigned() == 3768803088, 'unsigned uinthex == 3768803088') self.assertTrue( frame0.FindVariable('sinthex').GetValueAsUnsigned() == 3768803088, 'unsigned sinthex == 3768803088') self.assertTrue( frame0.FindVariable('uinthex').GetValueAsSigned() == -526164208, 'signed uinthex == -526164208') self.assertTrue( frame0.FindVariable('sinthex').GetValueAsSigned() == -526164208, 'signed sinthex == -526164208')
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 frame for current thread frame = thread.GetSelectedFrame() # Test chained calls test_result = frame.EvaluateExpression("get(set(true))") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "true", "get(set(true)) = true") test_result = frame.EvaluateExpression("get(set(false))") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(set(false)) = false") test_result = frame.EvaluateExpression("get(t & f)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(t & f) = false") test_result = frame.EvaluateExpression("get(f & t)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(f & t) = false") test_result = frame.EvaluateExpression("get(t & t)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "true", "get(t & t) = true") test_result = frame.EvaluateExpression("get(f & f)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(f & f) = false") test_result = frame.EvaluateExpression("get(t & f)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(t & f) = false") test_result = frame.EvaluateExpression("get(f) && get(t)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(f) && get(t) = false") test_result = frame.EvaluateExpression("get(f) && get(f)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "false", "get(f) && get(t) = false") test_result = frame.EvaluateExpression("get(t) && get(t)") self.assertTrue( test_result.IsValid() and test_result.GetValue() == "true", "get(t) && get(t) = true")
def test(self): """Test stepping over watchpoints.""" self.build() exe = os.path.join(os.getcwd(), 'a.out') target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) lldbutil.run_break_set_by_symbol(self, 'main') process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process.IsValid(), PROCESS_IS_VALID) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "Failed to get thread.") frame = thread.GetFrameAtIndex(0) self.assertTrue(frame.IsValid(), "Failed to get frame.") read_value = frame.FindValue('g_watch_me_read', lldb.eValueTypeVariableGlobal) self.assertTrue(read_value.IsValid(), "Failed to find read value.") error = lldb.SBError() # resolve_location=True, read=True, write=False read_watchpoint = read_value.Watch(True, True, False, error) self.assertTrue(error.Success(), "Error while setting watchpoint: %s" % error.GetCString()) self.assertTrue(read_watchpoint, "Failed to set read watchpoint.") thread.StepOver() self.assertTrue(thread.GetStopReason() == lldb.eStopReasonWatchpoint, STOPPED_DUE_TO_WATCHPOINT) self.assertTrue(thread.GetStopDescription(20) == 'watchpoint 1') process.Continue() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) self.assertTrue(thread.GetStopDescription(20) == 'step over') self.step_inst_for_watchpoint(1) write_value = frame.FindValue('g_watch_me_write', lldb.eValueTypeVariableGlobal) self.assertTrue(write_value, "Failed to find write value.") # Most of the MIPS boards provide only one H/W watchpoints, and S/W # watchpoints are not supported yet arch = self.getArchitecture() if re.match("^mips", arch): self.runCmd("watchpoint delete 1") # resolve_location=True, read=False, write=True write_watchpoint = write_value.Watch(True, False, True, error) self.assertTrue(write_watchpoint, "Failed to set write watchpoint.") self.assertTrue(error.Success(), "Error while setting watchpoint: %s" % error.GetCString()) thread.StepOver() self.assertTrue(thread.GetStopReason() == lldb.eStopReasonWatchpoint, STOPPED_DUE_TO_WATCHPOINT) self.assertTrue(thread.GetStopDescription(20) == 'watchpoint 2') process.Continue() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) self.assertTrue(thread.GetStopDescription(20) == 'step over') self.step_inst_for_watchpoint(2)
def breakpoint_conditions_python(self): """Use Python APIs to set breakpoint conditions.""" exe = self.getBuildArtifact("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.trace("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. # There's only one thread for the process. breakpoint.SetThreadIndex(1) 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 lldbsuite.test.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) # Test that the condition expression didn't create a result variable: options = lldb.SBExpressionOptions() value = frame0.EvaluateExpression("$0", options) self.assertTrue(value.GetError().Fail(), "Conditions should not make result variables.") process.Continue()
def test_stdcxx_disasm(self): """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # rdar://problem/8543077 # test/stl: clang built binaries results in the breakpoint locations = 3, # is this a problem with clang generated debug info? # # Break on line 13 of main.cpp. 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) # Now let's get the target as well as the process objects. target = self.dbg.GetSelectedTarget() process = target.GetProcess() # The process should be in a 'stopped' state. self.expect(str(process), STOPPED_DUE_TO_BREAKPOINT, exe=False, substrs=["a.out", "stopped"]) # Disassemble the functions on the call stack. self.runCmd("thread backtrace") thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) depth = thread.GetNumFrames() for i in range(depth - 1): frame = thread.GetFrameAtIndex(i) function = frame.GetFunction() if function.GetName(): self.runCmd("disassemble -n '%s'" % function.GetName()) lib_stdcxx = "FAILHORRIBLYHERE" # Iterate through the available modules, looking for stdc++ library... for i in range(target.GetNumModules()): module = target.GetModuleAtIndex(i) fs = module.GetFileSpec() if (fs.GetFilename().startswith("libstdc++") or fs.GetFilename().startswith("libc++")): lib_stdcxx = str(fs) break # At this point, lib_stdcxx is the full path to the stdc++ library and # module is the corresponding SBModule. self.expect(lib_stdcxx, "Libraray StdC++ is located", exe=False, substrs=["lib"]) self.runCmd("image dump symtab '%s'" % lib_stdcxx) raw_output = self.res.GetOutput() # Now, look for every 'Code' symbol and feed its load address into the # command: 'disassemble -s load_address -e end_address', where the # end_address is taken from the next consecutive 'Code' symbol entry's # load address. # # The load address column comes after the file address column, with both # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. codeRE = re.compile(r""" \ Code\ {9} # ' Code' followed by 9 SPCs, 0x[0-9a-f]{16} # the file address column, and \ # a SPC, and (0x[0-9a-f]{16}) # the load address column, and .* # the rest. """, re.VERBOSE) # Maintain a start address variable; if we arrive at a consecutive Code # entry, then the load address of the that entry is fed as the end # address to the 'disassemble -s SA -e LA' command. SA = None for line in raw_output.split(os.linesep): match = codeRE.search(line) if match: LA = match.group(1) if self.TraceOn(): print("line:", line) print("load address:", LA) print("SA:", SA) if SA and LA: if int(LA, 16) > int(SA, 16): self.runCmd("disassemble -s %s -e %s" % (SA, LA)) SA = LA else: # This entry is not a Code entry. Reset SA = None. SA = None
def do_test_breakpoint_location_hit_count(self): """Use Python APIs to check breakpoint hit count.""" exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Create a breakpoint in main.cpp by name 'a', # there should be two locations. breakpoint = target.BreakpointCreateByName('a', 'a.out') self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 2, VALID_BREAKPOINT) # Verify all breakpoint locations are enabled. location1 = breakpoint.GetLocationAtIndex(0) self.assertTrue(location1 and location1.IsEnabled(), VALID_BREAKPOINT_LOCATION) location2 = breakpoint.GetLocationAtIndex(1) self.assertTrue(location2 and location2.IsEnabled(), VALID_BREAKPOINT_LOCATION) # 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) # Verify 1st breakpoint location is hit. from lldbsuite.test.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) location1 = breakpoint.FindLocationByAddress(frame0.GetPC()) self.assertTrue( frame0.GetLineEntry().GetLine() == self.a_int_body_line_no, "Stopped in int a(int)") self.assertTrue(location1) self.assertEqual(location1.GetHitCount(), 1) self.assertEqual(breakpoint.GetHitCount(), 1) process.Continue() # Verify 2nd breakpoint location is hit. thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") frame0 = thread.GetFrameAtIndex(0) location2 = breakpoint.FindLocationByAddress(frame0.GetPC()) self.assertTrue( frame0.GetLineEntry().GetLine() == self.a_float_body_line_no, "Stopped in float a(float)") self.assertTrue(location2) self.assertEqual(location2.GetHitCount(), 1) self.assertEqual(location1.GetHitCount(), 1) self.assertEqual(breakpoint.GetHitCount(), 2) process.Continue() # Verify 2nd breakpoint location is hit again. thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") self.assertEqual(location2.GetHitCount(), 2) self.assertEqual(location1.GetHitCount(), 1) self.assertEqual(breakpoint.GetHitCount(), 3) 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. golden = thread.GetFrameAtIndex(0).FindVariable("golden") self.assertTrue( golden.IsValid(), "Encountered an error reading the process's golden variable") error = lldb.SBError() golden_str = process.ReadCStringFromMemory( golden.AddressOf().GetValueAsUnsigned(), 4096, error) self.assertTrue(error.Success()) self.assertTrue("c_as_C" in golden_str) # 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 golden_str.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): """Test the SBData APIs.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 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']) target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) frame = thread.GetSelectedFrame() foobar = frame.FindVariable('foobar') self.assertTrue(foobar.IsValid()) data = foobar.GetPointeeData(0, 2) offset = 0 error = lldb.SBError() self.assert_data(data.GetUnsignedInt32, offset, 1) offset += 4 low = data.GetSignedInt16(error, offset) self.assertSuccess(error) offset += 2 high = data.GetSignedInt16(error, offset) self.assertSuccess(error) offset += 2 self.assertTrue( (low == 9 and high == 0) or ( low == 0 and high == 9), 'foo[0].b == 9') self.assertTrue( fabs( data.GetFloat( error, offset) - 3.14) < 1, 'foo[0].c == 3.14') self.assertSuccess(error) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 8) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 5) offset += 4 self.runCmd("n") offset = 16 self.assert_data(data.GetUnsignedInt32, offset, 5) data = foobar.GetPointeeData(1, 1) offset = 0 self.assert_data(data.GetSignedInt32, offset, 8) offset += 4 self.assert_data(data.GetSignedInt32, offset, 7) offset += 8 self.assertTrue( data.GetUnsignedInt32( error, offset) == 0, 'do not read beyond end') self.assertTrue(not error.Success()) error.Clear() # clear the error for the next test star_foobar = foobar.Dereference() self.assertTrue(star_foobar.IsValid()) data = star_foobar.GetData() offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 1) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 9) foobar_addr = star_foobar.GetLoadAddress() foobar_addr += 12 # http://llvm.org/bugs/show_bug.cgi?id=11579 # lldb::SBValue::CreateValueFromAddress does not verify SBType::GetPointerType succeeds # This should not crash LLDB. nothing = foobar.CreateValueFromAddress( "nothing", foobar_addr, star_foobar.GetType().GetBasicType( lldb.eBasicTypeInvalid)) new_foobar = foobar.CreateValueFromAddress( "f00", foobar_addr, star_foobar.GetType()) self.assertTrue(new_foobar.IsValid()) data = new_foobar.GetData() self.assertEqual(data.uint32[0], 8, 'then foo[1].a == 8') self.assertEqual(data.uint32[1], 7, 'then foo[1].b == 7') # exploiting that sizeof(uint32) == sizeof(float) self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14') self.runCmd("n") offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 8) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 7) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 3.14) < 1, 'foo[1].c == 3.14') self.assertSuccess(error) data = new_foobar.GetData() offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 8) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 7) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 6.28) < 1, 'foo[1].c == 6.28') self.assertSuccess(error) self.runCmd("n") barfoo = frame.FindVariable('barfoo') data = barfoo.GetData() offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 1) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 2) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 3) < 1, 'barfoo[0].c == 3') self.assertSuccess(error) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 4) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 5) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 6) < 1, 'barfoo[1].c == 6') self.assertSuccess(error) new_object = barfoo.CreateValueFromData( "new_object", data, barfoo.GetType().GetBasicType( lldb.eBasicTypeInt)) self.assertEqual(new_object.GetValue(), "1", 'new_object == 1') if data.GetByteOrder() == lldb.eByteOrderBig: data.SetData( error, '\0\0\0A', data.GetByteOrder(), data.GetAddressByteSize()) else: data.SetData( error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize()) self.assertSuccess(error) data2 = lldb.SBData() data2.SetData( error, 'BCD', data.GetByteOrder(), data.GetAddressByteSize()) self.assertSuccess(error) data.Append(data2) # this breaks on EBCDIC offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 65) offset += 4 self.assert_data(data.GetUnsignedInt8, offset, 66) offset += 1 self.assert_data(data.GetUnsignedInt8, offset, 67) offset += 1 self.assert_data(data.GetUnsignedInt8, offset, 68) offset += 1 # check the new API calls introduced per LLVM llvm.org/prenhancement request # 11619 (Allow creating SBData values from arrays or primitives in # Python) hello_str = "hello!" data2 = lldb.SBData.CreateDataFromCString( process.GetByteOrder(), process.GetAddressByteSize(), hello_str) self.assertEqual(len(data2.uint8), len(hello_str)) self.assertEqual(data2.uint8[0], 104, 'h == 104') self.assertEqual(data2.uint8[1], 101, 'e == 101') self.assertEqual(data2.uint8[2], 108, 'l == 108') self.assert_data(data2.GetUnsignedInt8, 3, 108) # l self.assertEqual(data2.uint8[4], 111, 'o == 111') self.assert_data(data2.GetUnsignedInt8, 5, 33) # ! uint_lists = [[1, 2, 3, 4, 5], [int(i) for i in [1, 2, 3, 4, 5]]] int_lists = [[2, -2], [int(i) for i in [2, -2]]] for l in uint_lists: data2 = lldb.SBData.CreateDataFromUInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assert_data(data2.GetUnsignedInt64, 0, 1) self.assert_data(data2.GetUnsignedInt64, 8, 2) self.assert_data(data2.GetUnsignedInt64, 16, 3) self.assert_data(data2.GetUnsignedInt64, 24, 4) self.assert_data(data2.GetUnsignedInt64, 32, 5) self.assertTrue( data2.uint64s == [ 1, 2, 3, 4, 5], 'read_data_helper failure: data2 == [1,2,3,4,5]') for l in int_lists: data2 = lldb.SBData.CreateDataFromSInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assertTrue( data2.sint32[ 0:2] == [ 2, -2], 'signed32 data2 = [2,-2]') data2.Append( lldb.SBData.CreateDataFromSInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), int_lists[0])) self.assert_data(data2.GetSignedInt32, 0, 2) self.assert_data(data2.GetSignedInt32, 4, -2) self.assertTrue( data2.sint64[ 1:3] == [ 2, -2], 'signed64 data2 = [2,-2]') for l in int_lists: data2 = lldb.SBData.CreateDataFromSInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assert_data(data2.GetSignedInt64, 0, 2) self.assert_data(data2.GetSignedInt64, 8, -2) self.assertTrue( data2.sint64[ 0:2] == [ 2, -2], 'signed64 data2 = [2,-2]') for l in uint_lists: data2 = lldb.SBData.CreateDataFromUInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assert_data(data2.GetUnsignedInt32, 0, 1) self.assert_data(data2.GetUnsignedInt32, 4, 2) self.assert_data(data2.GetUnsignedInt32, 8, 3) self.assert_data(data2.GetUnsignedInt32, 12, 4) self.assert_data(data2.GetUnsignedInt32, 16, 5) bool_list = [True, True, False, False, True, False] data2 = lldb.SBData.CreateDataFromSInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.sint32[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'signed32 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromUInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.uint32[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'unsigned32 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromSInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.sint64[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'signed64 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromUInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.uint64[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'signed64 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromDoubleArray( process.GetByteOrder(), process.GetAddressByteSize(), [ 3.14, 6.28, 2.71]) self.assertTrue( fabs( data2.GetDouble( error, 0) - 3.14) < 0.5, 'double data2[0] = 3.14') self.assertSuccess(error) self.assertTrue( fabs( data2.GetDouble( error, 8) - 6.28) < 0.5, 'double data2[1] = 6.28') self.assertSuccess(error) self.assertTrue( fabs( data2.GetDouble( error, 16) - 2.71) < 0.5, 'double data2[2] = 2.71') self.assertSuccess(error) data2 = lldb.SBData() data2.SetDataFromCString(hello_str) self.assertEqual(len(data2.uint8), len(hello_str)) self.assert_data(data2.GetUnsignedInt8, 0, 104) self.assert_data(data2.GetUnsignedInt8, 1, 101) self.assert_data(data2.GetUnsignedInt8, 2, 108) self.assert_data(data2.GetUnsignedInt8, 3, 108) self.assert_data(data2.GetUnsignedInt8, 4, 111) self.assert_data(data2.GetUnsignedInt8, 5, 33) data2.SetDataFromUInt64Array([1, 2, 3, 4, 5]) self.assert_data(data2.GetUnsignedInt64, 0, 1) self.assert_data(data2.GetUnsignedInt64, 8, 2) self.assert_data(data2.GetUnsignedInt64, 16, 3) self.assert_data(data2.GetUnsignedInt64, 24, 4) self.assert_data(data2.GetUnsignedInt64, 32, 5) self.assertEqual( data2.uint64[0], 1, 'read_data_helper failure: set data2[0] = 1') self.assertEqual( data2.uint64[1], 2, 'read_data_helper failure: set data2[1] = 2') self.assertEqual( data2.uint64[2], 3, 'read_data_helper failure: set data2[2] = 3') self.assertEqual( data2.uint64[3], 4, 'read_data_helper failure: set data2[3] = 4') self.assertEqual( data2.uint64[4], 5, 'read_data_helper failure: set data2[4] = 5') self.assertTrue( data2.uint64[ 0:2] == [ 1, 2], 'read_data_helper failure: set data2[0:2] = [1,2]') data2.SetDataFromSInt32Array([2, -2]) self.assert_data(data2.GetSignedInt32, 0, 2) self.assert_data(data2.GetSignedInt32, 4, -2) data2.SetDataFromSInt64Array([2, -2]) self.assert_data(data2.GetSignedInt64, 0, 2) self.assert_data(data2.GetSignedInt64, 8, -2) data2.SetDataFromUInt32Array([1, 2, 3, 4, 5]) self.assert_data(data2.GetUnsignedInt32, 0, 1) self.assert_data(data2.GetUnsignedInt32, 4, 2) self.assert_data(data2.GetUnsignedInt32, 8, 3) self.assert_data(data2.GetUnsignedInt32, 12, 4) self.assert_data(data2.GetUnsignedInt32, 16, 5) self.assertEqual( data2.uint32[0], 1, 'read_data_helper failure: set 32-bit data2[0] = 1') self.assertEqual( data2.uint32[1], 2, 'read_data_helper failure: set 32-bit data2[1] = 2') self.assertEqual( data2.uint32[2], 3, 'read_data_helper failure: set 32-bit data2[2] = 3') self.assertEqual( data2.uint32[3], 4, 'read_data_helper failure: set 32-bit data2[3] = 4') self.assertEqual( data2.uint32[4], 5, 'read_data_helper failure: set 32-bit data2[4] = 5') data2.SetDataFromDoubleArray([3.14, 6.28, 2.71]) self.assertTrue(fabs(data2.GetDouble(error, 0) - 3.14) < 0.5, 'set double data2[0] = 3.14') self.assertTrue(fabs(data2.GetDouble(error, 8) - 6.28) < 0.5, 'set double data2[1] = 6.28') self.assertTrue(fabs(data2.GetDouble(error, 16) - 2.71) < 0.5, 'set double data2[2] = 2.71') self.assertTrue( fabs( data2.double[0] - 3.14) < 0.5, 'read_data_helper failure: set double data2[0] = 3.14') self.assertTrue( fabs( data2.double[1] - 6.28) < 0.5, 'read_data_helper failure: set double data2[1] = 6.28') self.assertTrue( fabs( data2.double[2] - 2.71) < 0.5, 'read_data_helper failure: set double data2[2] = 2.71')
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 test_watch_iter(self): """Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints.""" self.build() exe = self.getBuildArtifact("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, False, 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) self.assertTrue(watchpoint.IsEnabled()) watch_id = watchpoint.GetID() self.assertTrue(watch_id != 0) # Continue. Expect the program to stop due to the variable being # written to. process.Continue() # Hide stdout if not running with '-t' option. if not self.TraceOn(): self.HideStdout() # Print the stack traces. lldbutil.print_stacktraces(process) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) self.assertTrue(thread, "The thread stopped due to watchpoint") self.DebugSBValue(value) # We currently only support hardware watchpoint. Verify that we have a # meaningful hardware index at this point. Exercise the printed repr of # SBWatchpointLocation. print(watchpoint) if not self.affected_by_radar_34564183(): self.assertTrue(watchpoint.GetHardwareIndex() != -1) # SBWatchpoint.GetDescription() takes a description level arg. print(lldbutil.get_description(watchpoint, lldb.eDescriptionLevelFull)) # Now disable the 'rw' watchpoint. The program won't stop when it reads # 'global' next. watchpoint.SetEnabled(False) self.assertTrue(watchpoint.GetHardwareIndex() == -1) self.assertFalse(watchpoint.IsEnabled()) # Continue. The program does not stop again when the variable is being # read from because the watchpoint location has been disabled. process.Continue() # At this point, the inferior process should have exited. self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) # Verify some vital statistics and exercise the iterator API. for watchpoint in target.watchpoint_iter(): self.assertTrue(watchpoint) self.assertTrue(watchpoint.GetWatchSize() == 4) self.assertTrue(watchpoint.GetHitCount() == 1) print(watchpoint)
def test(self): """Exercise SBType and SBTypeList API.""" d = {'EXE': self.exe_name} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = self.getBuildArtifact(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) # Get the type 'Task'. type_list = target.FindTypes('Task') if self.TraceOn(): print( "Size of type_list from target.FindTypes('Task') query: %d" % type_list.GetSize()) # a second Task make be scared up by the Objective-C runtime self.assertTrue(len(type_list) >= 1) for type in type_list: self.assertTrue(type) self.DebugSBType(type) self.assertFalse(type.IsAnonymousType(), "Task is not anonymous") for field in type.fields: if field.name == "type": for enum_member in field.type.enum_members: self.assertTrue(enum_member) self.DebugSBType(enum_member.type) elif field.name == "my_type_is_nameless": self.assertTrue( field.type.IsAnonymousType(), "my_type_is_nameless has an anonymous type") elif field.name == "my_type_is_named": self.assertFalse( field.type.IsAnonymousType(), "my_type_is_named has a named type") # Pass an empty string. LLDB should not crash. :-) fuzz_types = target.FindTypes(None) fuzz_type = target.FindFirstType(None) # Now use the SBTarget.FindFirstType() API to find 'Task'. task_type = target.FindFirstType('Task') self.assertTrue(task_type) self.DebugSBType(task_type) # Get the reference type of 'Task', just for fun. task_ref_type = task_type.GetReferenceType() self.assertTrue(task_ref_type) self.DebugSBType(task_ref_type) # Get the pointer type of 'Task', which is the same as task_head's # type. task_pointer_type = task_type.GetPointerType() self.assertTrue(task_pointer_type) self.DebugSBType(task_pointer_type) # Get variable 'task_head'. task_head = frame0.FindVariable('task_head') self.assertTrue(task_head, VALID_VARIABLE) self.DebugSBValue(task_head) task_head_type = task_head.GetType() self.DebugSBType(task_head_type) self.assertTrue(task_head_type.IsPointerType()) self.assertTrue(task_head_type == task_pointer_type) # Get the pointee type of 'task_head'. task_head_pointee_type = task_head_type.GetPointeeType() self.DebugSBType(task_head_pointee_type) self.assertTrue(task_type == task_head_pointee_type) # We'll now get the child member 'id' from 'task_head'. id = task_head.GetChildMemberWithName('id') self.DebugSBValue(id) id_type = id.GetType() self.DebugSBType(id_type) # SBType.GetBasicType() takes an enum 'BasicType' # (lldb-enumerations.h). int_type = id_type.GetBasicType(lldb.eBasicTypeInt) self.assertTrue(id_type == int_type)
def test_and_python_api(self): """Use Python APIs to inspect variables with array types.""" self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.c", self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Sanity check the print representation of breakpoint. bp = str(breakpoint) self.expect(bp, msg="Breakpoint looks good", exe=False, substrs=["file = 'main.c'", "line = %d" % self.line, "locations = 1"]) self.expect( bp, msg="Breakpoint is not resolved as yet", exe=False, matching=False, substrs=["resolved = 1"]) # 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) # Sanity check the print representation of process. proc = str(process) self.expect(proc, msg="Process looks good", exe=False, substrs=["state = stopped", "executable = a.out"]) # The stop reason of the thread should be breakpoint. thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Sanity check the print representation of thread. thr = str(thread) # TODO(zturner): Whether the TID is printed in hex or decimal should be controlled by a setting, # and this test should read the value of the setting. This check is currently hardcoded to # match the check in Core/FormatEntity.cpp in the function FormatEntity::Format() for # the Entry::Type::ThreadID case of the switch statement. if self.getPlatform() == "linux" or self.getPlatform() == "freebsd": tidstr = "tid = %u" % thread.GetThreadID() else: tidstr = "tid = 0x%4.4x" % thread.GetThreadID() self.expect( thr, "Thread looks good with stop reason = breakpoint", exe=False, substrs=[tidstr]) # The breakpoint should have a hit count of 1. self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) # The breakpoint should be resolved by now. bp = str(breakpoint) self.expect(bp, "Breakpoint looks good and is resolved", exe=False, substrs=["file = 'main.c'", "line = %d" % self.line, "locations = 1"]) # Sanity check the print representation of frame. frame = thread.GetFrameAtIndex(0) frm = str(frame) self.expect( frm, "Frame looks good with correct index %d" % frame.GetFrameID(), exe=False, substrs=[ "#%d" % frame.GetFrameID()]) # Lookup the "strings" string array variable and sanity check its print # representation. variable = frame.FindVariable("strings") var = str(variable) self.expect( var, "Variable for 'strings' looks good with correct name", exe=False, substrs=[ "%s" % variable.GetName()]) self.DebugSBValue(variable) self.assertEquals(variable.GetNumChildren(), 4, "Variable 'strings' should have 4 children") byte_size = variable.GetByteSize() self.assertTrue(byte_size >= 4*4 and byte_size <= 1024) child3 = variable.GetChildAtIndex(3) self.DebugSBValue(child3) self.assertEquals(child3.GetSummary(), '"Guten Tag"', 'strings[3] == "Guten Tag"') # Lookup the "char_16" char array variable. variable = frame.FindVariable("char_16") self.DebugSBValue(variable) self.assertEquals(variable.GetNumChildren(), 16, "Variable 'char_16' should have 16 children") # Lookup the "ushort_matrix" ushort[] array variable. # Notice the pattern of int(child0_2.GetValue(), 0). We pass a # base of 0 so that the proper radix is determined based on the contents # of the string. Same applies to long(). variable = frame.FindVariable("ushort_matrix") self.DebugSBValue(variable) self.assertEquals(variable.GetNumChildren(), 2, "Variable 'ushort_matrix' should have 2 children") child0 = variable.GetChildAtIndex(0) self.DebugSBValue(child0) self.assertEquals(child0.GetNumChildren(), 3, "Variable 'ushort_matrix[0]' should have 3 children") child0_2 = child0.GetChildAtIndex(2) self.DebugSBValue(child0_2) self.assertEquals(int(child0_2.GetValue(), 0), 3, "ushort_matrix[0][2] == 3") # Lookup the "long_6" char array variable. variable = frame.FindVariable("long_6") self.DebugSBValue(variable) self.assertEquals(variable.GetNumChildren(), 6, "Variable 'long_6' should have 6 children") child5 = variable.GetChildAtIndex(5) self.DebugSBValue(child5) self.assertEquals(int(child5.GetValue(), 0), 6, "long_6[5] == 6") # Last, check that "long_6" has a value type of eValueTypeVariableLocal # and "argc" has eValueTypeVariableArgument. from lldbsuite.test.lldbutil import value_type_to_str self.assertEqual( variable.GetValueType(), lldb.eValueTypeVariableLocal, "Variable 'long_6' should have '%s' value type." % value_type_to_str( lldb.eValueTypeVariableLocal)) argc = frame.FindVariable("argc") self.DebugSBValue(argc) self.assertEquals(argc.GetValueType(), lldb.eValueTypeVariableArgument, "Variable 'argc' should have '%s' value type." % value_type_to_str(lldb.eValueTypeVariableArgument))
def test_with_python_api(self): """Test Python APIs on file and class static variables.""" 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) # 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. thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Get the SBValue of 'A::g_points' and 'g_points'. frame = thread.GetFrameAtIndex(0) # arguments => False # locals => False # statics => True # in_scope_only => False valList = frame.GetVariables(False, False, True, False) for val in valList: self.DebugSBValue(val) name = val.GetName() self.assertTrue(name in ['g_points', 'A::g_points']) if name == 'g_points': self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableStatic) self.assertTrue(val.GetNumChildren() == 2) elif name == 'A::g_points': self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableGlobal) self.assertTrue(val.GetNumChildren() == 2) child1 = val.GetChildAtIndex(1) self.DebugSBValue(child1) child1_x = child1.GetChildAtIndex(0) self.DebugSBValue(child1_x) self.assertTrue(child1_x.GetTypeName() == 'int' and child1_x.GetValue() == '11') # SBFrame.FindValue() should also work. val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal) self.DebugSBValue(val) self.assertTrue(val.GetName() == 'A::g_points') # Also exercise the "parameter" and "local" scopes while we are at it. val = frame.FindValue("argc", lldb.eValueTypeVariableArgument) self.DebugSBValue(val) self.assertTrue(val.GetName() == 'argc') val = frame.FindValue("argv", lldb.eValueTypeVariableArgument) self.DebugSBValue(val) self.assertTrue(val.GetName() == 'argv') val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal) self.DebugSBValue(val) self.assertTrue(val.GetName() == 'hello_world')
def test_access_my_int(self): """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs.""" self.build() exe = self.getBuildArtifact("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_int'. val = frame.FindValue("my_int", 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) # Note that the canonical from of the bytearray is little endian. from lldbsuite.test.lldbutil import int_to_bytearray, bytearray_to_int byteSize = val.GetByteSize() bytes = int_to_bytearray(256, byteSize) byteOrder = process.GetByteOrder() if byteOrder == lldb.eByteOrderBig: bytes.reverse() elif byteOrder == lldb.eByteOrderLittle: pass else: # Neither big endian nor little endian? Return for now. # Add more logic here if we want to handle other types. return # The program logic makes the 'my_int' variable to have int type and value of 0. # But we want to use the WriteMemory() API to assign 256 to the # variable. # Now use WriteMemory() API to write 256 into the global variable. error = lldb.SBError() result = process.WriteMemory(location, bytes, error) if not error.Success() or result != byteSize: self.fail("SBProcess.WriteMemory() failed") # Make sure that the val we got originally updates itself to notice the # change: self.expect( val.GetValue(), "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'", exe=False, startstr='256') # And for grins, get the SBValue for the global variable 'my_int' # again, to make sure that also tracks the new value: val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal) self.expect( val.GetValue(), "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'", exe=False, startstr='256') # Now read the memory content. The bytearray should have (byte)1 as # the second element. content = process.ReadMemory(location, byteSize, error) if not error.Success(): self.fail("SBProcess.ReadMemory() failed") # The bytearray_to_int utility function expects a little endian # bytearray. if byteOrder == lldb.eByteOrderBig: content = bytearray(content, 'ascii') content.reverse() new_value = bytearray_to_int(content, byteSize) if new_value != 256: self.fail( "Memory content read from 'my_int' does not match (int)256") # Dump the memory content.... if self.TraceOn(): for i in content: print("byte:", i)