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