1""" 2Test the lldb disassemble command on foundation framework. 3""" 4 5import unittest2 6import os 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class FoundationDisassembleTestCase(TestBase): 14 15 NO_DEBUG_INFO_TESTCASE = True 16 17 @skipIfAsan 18 def test_foundation_disasm(self): 19 """Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework.""" 20 self.build() 21 22 # Enable synchronous mode 23 self.dbg.SetAsync(False) 24 25 # Create a target by the debugger. 26 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 27 self.assertTrue(target, VALID_TARGET) 28 29 # Now launch the process, and do not stop at entry point. 30 process = target.LaunchSimple( 31 None, None, self.get_process_working_directory()) 32 self.assertTrue(process, PROCESS_IS_VALID) 33 34 foundation_framework = None 35 for module in target.modules: 36 if module.file.basename == "Foundation": 37 foundation_framework = module.file.fullpath 38 break 39 40 self.assertTrue( 41 foundation_framework is not None, 42 "Foundation.framework path located") 43 self.runCmd("image dump symtab '%s'" % foundation_framework) 44 raw_output = self.res.GetOutput() 45 # Now, grab every 'Code' symbol and feed it into the command: 46 # 'disassemble -n func'. 47 # 48 # The symbol name is on the last column and trails the flag column which 49 # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. 50 codeRE = re.compile(r""" 51 \ Code\ {9} # ' Code' followed by 9 SPCs, 52 .* # the wildcard chars, 53 0x[0-9a-f]{8} # the flag column, and 54 \ (.+)$ # finally the function symbol. 55 """, re.VERBOSE) 56 for line in raw_output.split(os.linesep): 57 match = codeRE.search(line) 58 if match: 59 func = match.group(1) 60 self.runCmd('image lookup -s "%s"' % func) 61 self.runCmd('disassemble --force -n "%s"' % func) 62 63 @skipIfAsan 64 def test_simple_disasm(self): 65 """Test the lldb 'disassemble' command""" 66 self.build() 67 68 # Create a target by the debugger. 69 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 70 self.assertTrue(target, VALID_TARGET) 71 72 # Stop at +[NSString stringWithFormat:]. 73 symbol_name = "+[NSString stringWithFormat:]" 74 break_results = lldbutil.run_break_set_command( 75 self, "_regexp-break %s" % (symbol_name)) 76 77 lldbutil.check_breakpoint_result( 78 self, 79 break_results, 80 symbol_name=symbol_name, 81 num_locations=1) 82 83 # Stop at -[MyString initWithNSString:]. 84 lldbutil.run_break_set_by_symbol( 85 self, 86 '-[MyString initWithNSString:]', 87 num_expected_locations=1, 88 sym_exact=True) 89 90 # Stop at the "description" selector. 91 lldbutil.run_break_set_by_selector( 92 self, 93 'description', 94 num_expected_locations=1, 95 module_name='a.out') 96 97 # Stop at -[NSAutoreleasePool release]. 98 break_results = lldbutil.run_break_set_command( 99 self, "_regexp-break -[NSAutoreleasePool release]") 100 lldbutil.check_breakpoint_result( 101 self, 102 break_results, 103 symbol_name='-[NSAutoreleasePool release]', 104 num_locations=1) 105 106 self.runCmd("run", RUN_SUCCEEDED) 107 108 # First stop is +[NSString stringWithFormat:]. 109 self.expect( 110 "thread backtrace", 111 "Stop at +[NSString stringWithFormat:]", 112 substrs=["Foundation`+[NSString stringWithFormat:]"]) 113 114 # Do the disassemble for the currently stopped function. 115 self.runCmd("disassemble -f") 116 117 self.runCmd("process continue") 118 # Skip another breakpoint for +[NSString stringWithFormat:]. 119 self.runCmd("process continue") 120 121 # Followed by a.out`-[MyString initWithNSString:]. 122 self.expect( 123 "thread backtrace", 124 "Stop at a.out`-[MyString initWithNSString:]", 125 substrs=["a.out`-[MyString initWithNSString:]"]) 126 127 # Do the disassemble for the currently stopped function. 128 self.runCmd("disassemble -f") 129 130 self.runCmd("process continue") 131 132 # Followed by -[MyString description]. 133 self.expect("thread backtrace", "Stop at -[MyString description]", 134 substrs=["a.out`-[MyString description]"]) 135 136 # Do the disassemble for the currently stopped function. 137 self.runCmd("disassemble -f") 138 139 self.runCmd("process continue") 140 # Skip another breakpoint for -[MyString description]. 141 self.runCmd("process continue") 142 143 # Followed by -[NSAutoreleasePool release]. 144 self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]", 145 substrs=["Foundation`-[NSAutoreleasePool release]"]) 146 147 # Do the disassemble for the currently stopped function. 148 self.runCmd("disassemble -f") 149