TestTargetAPI.py revision 329bb8bf2aa73889358bb131937e48cc4f23ca3a
1""" 2Test SBTarget APIs. 3""" 4 5import os, time 6import re 7import unittest2 8import lldb, lldbutil 9from lldbtest import * 10 11class TargetAPITestCase(TestBase): 12 13 mydir = os.path.join("python_api", "target") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @python_api_test 17 def test_launch_new_process_and_redirect_stdout_with_dsym(self): 18 """Exercise SBTaget.Launch() API.""" 19 self.buildDsym() 20 self.launch_new_process_and_redirect_stdout() 21 22 @python_api_test 23 def test_launch_new_process_and_redirect_stdout_with_dwarf(self): 24 """Exercise SBTarget.Launch() API.""" 25 self.buildDwarf() 26 self.launch_new_process_and_redirect_stdout() 27 28 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 29 @python_api_test 30 def test_resolve_symbol_context_with_address_with_dsym(self): 31 """Exercise SBTaget.ResolveSymbolContextForAddress() API.""" 32 self.buildDsym() 33 self.resolve_symbol_context_with_address() 34 35 @python_api_test 36 def test_resolve_symbol_context_with_address_with_dwarf(self): 37 """Exercise SBTarget.ResolveSymbolContextForAddress() API.""" 38 self.buildDwarf() 39 self.resolve_symbol_context_with_address() 40 41 def setUp(self): 42 # Call super's setUp(). 43 TestBase.setUp(self) 44 # Find the line number to of function 'c'. 45 self.line1 = line_number('main.c', '// Find the line number for breakpoint 1 here.') 46 self.line2 = line_number('main.c', '// Find the line number for breakpoint 2 here.') 47 48 def launch_new_process_and_redirect_stdout(self): 49 """Exercise SBTaget.Launch() API with redirected stdout.""" 50 exe = os.path.join(os.getcwd(), "a.out") 51 52 # Create a target by the debugger. 53 target = self.dbg.CreateTarget(exe) 54 self.assertTrue(target.IsValid(), VALID_TARGET) 55 56 # Add an extra twist of stopping the inferior in a breakpoint, and then continue till it's done. 57 # We should still see the entire stdout redirected once the process is finished. 58 line = line_number('main.c', '// a(3) -> c(3)') 59 breakpoint = target.BreakpointCreateByLocation('main.c', line) 60 61 # Now launch the process, do not stop at entry point, and redirect stdout to "stdout.txt" file. 62 # The inferior should run to completion after "process.Continue()" call, so there's no need 63 # to assign to self.process to have the inferior kiiled during test teardown. 64 error = lldb.SBError() 65 process = target.Launch (self.dbg.GetListener(), None, None, None, "stdout.txt", None, None, 0, False, error) 66 process.Continue() 67 #self.runCmd("process status") 68 69 # The 'stdout.txt' file should now exist. 70 self.assertTrue(os.path.isfile("stdout.txt"), 71 "'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.") 72 73 # Read the output file produced by running the program. 74 with open('stdout.txt', 'r') as f: 75 output = f.read() 76 77 # Let's delete the 'stdout.txt' file as a cleanup step. 78 try: 79 os.remove("stdout.txt") 80 pass 81 except OSError: 82 pass 83 84 self.expect(output, exe=False, 85 substrs = ["a(1)", "b(2)", "a(3)"]) 86 87 88 def resolve_symbol_context_with_address(self): 89 """Exercise SBTaget.ResolveSymbolContextForAddress() API.""" 90 exe = os.path.join(os.getcwd(), "a.out") 91 92 # Create a target by the debugger. 93 target = self.dbg.CreateTarget(exe) 94 self.assertTrue(target.IsValid(), VALID_TARGET) 95 96 # Now create the two breakpoints inside function 'a'. 97 breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) 98 breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) 99 #print "breakpoint1:", breakpoint1 100 #print "breakpoint2:", breakpoint2 101 self.assertTrue(breakpoint1.IsValid() and 102 breakpoint1.GetNumLocations() == 1, 103 VALID_BREAKPOINT) 104 self.assertTrue(breakpoint2.IsValid() and 105 breakpoint2.GetNumLocations() == 1, 106 VALID_BREAKPOINT) 107 108 # Now launch the process, and do not stop at entry point. 109 error = lldb.SBError() 110 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) 111 112 self.process = target.GetProcess() 113 self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) 114 115 # Frame #0 should be on self.line1. 116 self.assertTrue(self.process.GetState() == lldb.eStateStopped) 117 thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint) 118 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") 119 #self.runCmd("process status") 120 frame0 = thread.GetFrameAtIndex(0) 121 lineEntry = frame0.GetLineEntry() 122 self.assertTrue(lineEntry.GetLine() == self.line1) 123 124 address1 = lineEntry.GetStartAddress() 125 126 # Continue the inferior, the breakpoint 2 should be hit. 127 self.process.Continue() 128 self.assertTrue(self.process.GetState() == lldb.eStateStopped) 129 thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint) 130 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") 131 #self.runCmd("process status") 132 frame0 = thread.GetFrameAtIndex(0) 133 lineEntry = frame0.GetLineEntry() 134 self.assertTrue(lineEntry.GetLine() == self.line2) 135 136 address2 = lineEntry.GetStartAddress() 137 138 #print "address1:", address1 139 #print "address2:", address2 140 141 # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses from our line entry. 142 context1 = target.ResolveSymbolContextForAddress(address1, lldb.eSymbolContextEverything) 143 context2 = target.ResolveSymbolContextForAddress(address2, lldb.eSymbolContextEverything) 144 145 self.assertTrue(context1.IsValid() and context2.IsValid()) 146 #print "context1:", context1 147 #print "context2:", context2 148 149 # Verify that the context point to the same function 'a'. 150 symbol1 = context1.GetSymbol() 151 symbol2 = context2.GetSymbol() 152 self.assertTrue(symbol1.IsValid() and symbol2.IsValid()) 153 #print "symbol1:", symbol1 154 #print "symbol2:", symbol2 155 156 stream1 = lldb.SBStream() 157 symbol1.GetDescription(stream1) 158 stream2 = lldb.SBStream() 159 symbol2.GetDescription(stream2) 160 161 self.expect(stream1.GetData(), "The two addresses should resolve to the same symbol", exe=False, 162 startstr = stream2.GetData()) 163 164 165if __name__ == '__main__': 166 import atexit 167 lldb.SBDebugger.Initialize() 168 atexit.register(lambda: lldb.SBDebugger.Terminate()) 169 unittest2.main() 170