TestStdCXXDisassembly.py revision 0910eb32b94bd67b0357d34d0951aad197742569
190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen""" 254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny ChenTest the lldb disassemble command on lib stdc++. 390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen""" 490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenimport os, time 690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenimport unittest2 790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenimport lldb 890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenfrom lldbtest import * 990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 1090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenclass StdCXXDisassembleTestCase(TestBase): 1190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 1290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen mydir = "stl" 1390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 1445ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen def setUp(self): 150910eb32b94bd67b0357d34d0951aad197742569Johnny Chen # Call super's setUp(). 160910eb32b94bd67b0357d34d0951aad197742569Johnny Chen TestBase.setUp(self) 1745ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # Find the line number to break inside main(). 1845ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen self.line = line_number('main.cpp', '// Set break point at this line.') 1945ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen 2054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # rdar://problem/8504895 2154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]" 2290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test") 2390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen def test_stdcxx_disasm(self): 2490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib.""" 2590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.buildDefault() 2690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen exe = os.path.join(os.getcwd(), "a.out") 2790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 2890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 2945ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # rdar://problem/8543077 3045ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # test/stl: clang built binaries results in the breakpoint locations = 3, 3145ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # is this a problem with clang generated debug info? 3245ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # 3390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # Break on line 13 of main.cpp. 3445ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen self.expect("breakpoint set -f main.cpp -l %d" % self.line, 3545ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen BREAKPOINT_CREATED, 3645ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" % 3745ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen self.line) 3890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 3990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.runCmd("run", RUN_SUCCEEDED) 4090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 4190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # Now let's get the target as well as the process objects. 4290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen target = self.dbg.GetSelectedTarget() 4390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen process = target.GetProcess() 4490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 4590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # The process should be in a 'Stopped' state. 4690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.expect(repr(process), STOPPED_DUE_TO_BREAKPOINT, exe=False, 4790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen substrs = ["a.out", 488e468594632a43f2062d5a364224ac15fddfdef2Johnny Chen "Stopped"]) 4990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 5054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Disassemble the functions on the call stack. 5154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen self.runCmd("thread backtrace") 5254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen thread = process.GetThreadAtIndex(0) 5354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen depth = thread.GetNumFrames() 5454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen for i in range(depth - 1): 5554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen frame = thread.GetFrameAtIndex(i) 5654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen function = frame.GetFunction() 5754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen self.runCmd("disassemble -n '%s'" % function.GetName()) 5854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen 5990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # Iterate through the available modules, looking for stdc++ library... 6090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen for i in range(target.GetNumModules()): 6190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen module = target.GetModuleAtIndex(i) 6290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen fs = module.GetFileSpec() 6390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen if (fs.GetFilename().startswith("libstdc++")): 6490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen lib_stdcxx = repr(fs) 6590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen break 6690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 6790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # At this point, lib_stdcxx is the full path to the stdc++ library and 6890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # module is the corresponding SBModule. 6990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 7090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.expect(fs.GetFilename(), "Libraray StdC++ is located", exe=False, 7190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen substrs = ["libstdc++"]) 7290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 7354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen self.runCmd("image dump symtab %s" % repr(fs)) 7454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen raw_output = self.res.GetOutput() 7554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Now, look for every 'Code' symbol and feed its load address into the 7654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # command: 'disassemble -s load_address -e end_address', where the 7754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # end_address is taken from the next consecutive 'Code' symbol entry's 7854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # load address. 7954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # 8054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # The load address column comes after the file address column, with both 8154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. 8254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen codeRE = re.compile(r""" 8354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen \ Code\ {9} # ' Code' followed by 9 SPCs, 8454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen 0x[0-9a-f]{16} # the file address column, and 8554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen \ # a SPC, and 8654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen (0x[0-9a-f]{16}) # the load address column, and 8754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen .* # the rest. 8854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen """, re.VERBOSE) 8954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Maintain a start address variable; if we arrive at a consecutive Code 9054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # entry, then the load address of the that entry is fed as the end 9154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # address to the 'disassemble -s SA -e LA' command. 9254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen SA = None 9354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen for line in raw_output.split(os.linesep): 9454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen match = codeRE.search(line) 9554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen if match: 9654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen LA = match.group(1) 9754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen print "line:", line 9854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen print "load address:", LA 9954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen print "SA:", SA 10054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen if SA and LA: 10154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen self.runCmd("disassemble -s %s -e %s" % (SA, LA)) 10254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen SA = LA 10354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen else: 10454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # This entry is not a Code entry. Reset SA = None. 10554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen SA = None 10654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen 10790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 10890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenif __name__ == '__main__': 10990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen import atexit 11090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen lldb.SBDebugger.Initialize() 11190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen atexit.register(lambda: lldb.SBDebugger.Terminate()) 11290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen unittest2.main() 113