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