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