1 """ 2 Test the lldb disassemble command on foundation framework. 3 """ 4 5 import os, time 6 import unittest2 7 import lldb 8 from lldbtest import * 9 import lldbutil 10 11 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 12 class FoundationDisassembleTestCase(TestBase): 13 14 mydir = os.path.join("lang", "objc", "foundation") 15 16 # rdar://problem/8504895 17 # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]" 18 @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test") 19 def test_foundation_disasm(self): 20 """Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework.""" 21 self.buildDefault() 22 exe = os.path.join(os.getcwd(), "a.out") 23 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 24 self.runCmd("run", RUN_SUCCEEDED) 25 26 self.runCmd("image list") 27 raw_output = self.res.GetOutput() 28 # Grok the full path to the foundation framework. 29 for line in raw_output.split(os.linesep): 30 match = re.search(" (/.*/Foundation.framework/.*)$", line) 31 if match: 32 foundation_framework = match.group(1) 33 break 34 35 self.assertTrue(match, "Foundation.framework path located") 36 self.runCmd("image dump symtab %s" % foundation_framework) 37 raw_output = self.res.GetOutput() 38 # Now, grab every 'Code' symbol and feed it into the command: 39 # 'disassemble -n func'. 40 # 41 # The symbol name is on the last column and trails the flag column which 42 # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. 43 codeRE = re.compile(r""" 44 \ Code\ {9} # ' Code' followed by 9 SPCs, 45 .* # the wildcard chars, 46 0x[0-9a-f]{8} # the flag column, and 47 \ (.+)$ # finally the function symbol. 48 """, re.VERBOSE) 49 for line in raw_output.split(os.linesep): 50 match = codeRE.search(line) 51 if match: 52 func = match.group(1) 53 #print "line:", line 54 #print "func:", func 55 self.runCmd('disassemble -n "%s"' % func) 56 57 58 @dsym_test 59 def test_simple_disasm_with_dsym(self): 60 """Test the lldb 'disassemble' command""" 61 self.buildDsym() 62 self.do_simple_disasm() 63 64 @dwarf_test 65 def test_simple_disasm_with_dwarf(self): 66 """Test the lldb 'disassemble' command""" 67 self.buildDwarf() 68 self.do_simple_disasm() 69 70 def do_simple_disasm(self): 71 """Do a bunch of simple disassemble commands.""" 72 exe = os.path.join(os.getcwd(), "a.out") 73 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 74 75 # Stop at +[NSString stringWithFormat:]. 76 symbol_name = "+[NSString stringWithFormat:]" 77 break_results = lldbutil.run_break_set_command (self, "_regexp-break %s"%(symbol_name)) 78 lldbutil.check_breakpoint_result (self, break_results, symbol_name=symbol_name, num_locations=1) 79 80 # Stop at -[MyString initWithNSString:]. 81 lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True) 82 83 # Stop at the "description" selector. 84 lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out') 85 86 # Stop at -[NSAutoreleasePool release]. 87 break_results = lldbutil.run_break_set_command (self, "_regexp-break -[NSAutoreleasePool release]") 88 lldbutil.check_breakpoint_result (self, break_results, symbol_name='-[NSAutoreleasePool release]', num_locations=1) 89 90 self.runCmd("run", RUN_SUCCEEDED) 91 92 # First stop is +[NSString stringWithFormat:]. 93 self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]", 94 substrs = ["Foundation`+[NSString stringWithFormat:]"]) 95 96 # Do the disassemble for the currently stopped function. 97 self.runCmd("disassemble -f") 98 99 self.runCmd("process continue") 100 # Skip another breakpoint for +[NSString stringWithFormat:]. 101 self.runCmd("process continue") 102 103 # Followed by a.out`-[MyString initWithNSString:]. 104 self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]", 105 substrs = ["a.out`-[MyString initWithNSString:]"]) 106 107 # Do the disassemble for the currently stopped function. 108 self.runCmd("disassemble -f") 109 110 self.runCmd("process continue") 111 112 # Followed by -[MyString description]. 113 self.expect("thread backtrace", "Stop at -[MyString description]", 114 substrs = ["a.out`-[MyString description]"]) 115 116 # Do the disassemble for the currently stopped function. 117 self.runCmd("disassemble -f") 118 119 self.runCmd("process continue") 120 # Skip another breakpoint for -[MyString description]. 121 self.runCmd("process continue") 122 123 # Followed by -[NSAutoreleasePool release]. 124 self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]", 125 substrs = ["Foundation`-[NSAutoreleasePool release]"]) 126 127 # Do the disassemble for the currently stopped function. 128 self.runCmd("disassemble -f") 129 130 131 if __name__ == '__main__': 132 import atexit 133 lldb.SBDebugger.Initialize() 134 atexit.register(lambda: lldb.SBDebugger.Terminate()) 135 unittest2.main() 136