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 * 9431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil 1090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 1190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenclass StdCXXDisassembleTestCase(TestBase): 1290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 13b26db29eebfbc2dc88776afa738a9b6a8fcc8f75Johnny Chen mydir = os.path.join("lang", "cpp", "stl") 1490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 1545ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen def setUp(self): 160910eb32b94bd67b0357d34d0951aad197742569Johnny Chen # Call super's setUp(). 170910eb32b94bd67b0357d34d0951aad197742569Johnny Chen TestBase.setUp(self) 1845ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # Find the line number to break inside main(). 1945ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen self.line = line_number('main.cpp', '// Set break point at this line.') 2045ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen 2154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # rdar://problem/8504895 2254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]" 2390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test") 2490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen def test_stdcxx_disasm(self): 2590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib.""" 2690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.buildDefault() 2790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen exe = os.path.join(os.getcwd(), "a.out") 2890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 2990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 3045ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # rdar://problem/8543077 3145ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # test/stl: clang built binaries results in the breakpoint locations = 3, 3245ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # is this a problem with clang generated debug info? 3345ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen # 3490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # Break on line 13 of main.cpp. 35431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 3690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 3790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.runCmd("run", RUN_SUCCEEDED) 3890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 3990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # Now let's get the target as well as the process objects. 4090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen target = self.dbg.GetSelectedTarget() 4190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen process = target.GetProcess() 4290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 438a87d5244a61570e06f9b48b9bc04773e82e301eJohnny Chen # The process should be in a 'stopped' state. 440a19a1b9c25117854f226256805239d95153ed2dGreg Clayton self.expect(str(process), STOPPED_DUE_TO_BREAKPOINT, exe=False, 4590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen substrs = ["a.out", 468a87d5244a61570e06f9b48b9bc04773e82e301eJohnny Chen "stopped"]) 4790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 4854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Disassemble the functions on the call stack. 4954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen self.runCmd("thread backtrace") 5054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen thread = process.GetThreadAtIndex(0) 5154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen depth = thread.GetNumFrames() 5254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen for i in range(depth - 1): 5354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen frame = thread.GetFrameAtIndex(i) 5454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen function = frame.GetFunction() 5554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen self.runCmd("disassemble -n '%s'" % function.GetName()) 5654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen 5790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # Iterate through the available modules, looking for stdc++ library... 5890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen for i in range(target.GetNumModules()): 5990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen module = target.GetModuleAtIndex(i) 6090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen fs = module.GetFileSpec() 6190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen if (fs.GetFilename().startswith("libstdc++")): 620a19a1b9c25117854f226256805239d95153ed2dGreg Clayton lib_stdcxx = str(fs) 6390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen break 6490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 6590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # At this point, lib_stdcxx is the full path to the stdc++ library and 6690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen # module is the corresponding SBModule. 6790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 6890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen self.expect(fs.GetFilename(), "Libraray StdC++ is located", exe=False, 6990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen substrs = ["libstdc++"]) 7090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen 710a19a1b9c25117854f226256805239d95153ed2dGreg Clayton self.runCmd("image dump symtab %s" % str(fs)) 7254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen raw_output = self.res.GetOutput() 7354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Now, look for every 'Code' symbol and feed its load address into the 7454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # command: 'disassemble -s load_address -e end_address', where the 7554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # end_address is taken from the next consecutive 'Code' symbol entry's 7654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # load address. 7754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # 7854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # The load address column comes after the file address column, with both 7954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. 8054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen codeRE = re.compile(r""" 8154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen \ Code\ {9} # ' Code' followed by 9 SPCs, 8254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen 0x[0-9a-f]{16} # the file address column, and 8354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen \ # a SPC, and 8454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen (0x[0-9a-f]{16}) # the load address column, and 8554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen .* # the rest. 8654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen """, re.VERBOSE) 8754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # Maintain a start address variable; if we arrive at a consecutive Code 8854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # entry, then the load address of the that entry is fed as the end 8954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen # address to the 'disassemble -s SA -e LA' command. 9054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen SA = None 9154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen for line in raw_output.split(os.linesep): 9254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen match = codeRE.search(line) 9354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen if match: 9454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen LA = match.group(1) 95df18b15f8693be6c876a9d34bf2cec5f3a4f7111Johnny Chen if self.TraceOn(): 96df18b15f8693be6c876a9d34bf2cec5f3a4f7111Johnny Chen print "line:", line 97df18b15f8693be6c876a9d34bf2cec5f3a4f7111Johnny Chen print "load address:", LA 98df18b15f8693be6c876a9d34bf2cec5f3a4f7111Johnny Chen print "SA:", SA 9954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen if SA and LA: 100df18b15f8693be6c876a9d34bf2cec5f3a4f7111Johnny Chen if int(LA, 16) > int(SA, 16): 101df18b15f8693be6c876a9d34bf2cec5f3a4f7111Johnny 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