summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py
blob: 345e41b2b04ea210de8889e8cdd24f07e2f84eb6 (plain)
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
158
159
160
161
162
"""
Test the lldb disassemble command on foundation framework.
"""

from __future__ import print_function


import unittest2
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


@skipUnlessDarwin
class FoundationDisassembleTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    # rdar://problem/8504895
    # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]"
    @unittest2.skipIf(
        TestBase.skipLongRunningTest(),
        "Skip this long running test")
    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:
            print(module)
            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)
                #print("line:", line)
                #print("func:", func)
                self.runCmd('disassemble -n "%s"' % func)

    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)

        print(target)
        for module in target.modules:
            print(module)

        # 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")
OpenPOWER on IntegriCloud