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