TestFoundationDisassembly.py revision b8025be2976a40d072e9a6d4eb7c9316d65bb16e
1c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen"""
254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny ChenTest the lldb disassemble command on foundation framework.
3c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen"""
4c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
5c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenimport os, time
6c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenimport unittest2
7c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenimport lldb
8c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenfrom lldbtest import *
9c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
10c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
11c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenclass FoundationDisassembleTestCase(TestBase):
12c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
13b8025be2976a40d072e9a6d4eb7c9316d65bb16eJohnny Chen    mydir = os.path.join("lang", "objc", "foundation")
14c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
1541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    # rdar://problem/8504895
1641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]"
1741998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
1841998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    def test_foundation_disasm(self):
1941998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        """Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework."""
2041998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.buildDefault()
2141998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
2241998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
2341998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
2441998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
2541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("image list")
2641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        raw_output = self.res.GetOutput()
2741998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        # Grok the full path to the foundation framework.
2841998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        for line in raw_output.split(os.linesep):
2941998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen            match = re.search(" (/.*/Foundation.framework/.*)$", line)
3041998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen            if match:
3141998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                foundation_framework = match.group(1)
3241998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                break
3341998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
3441998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.assertTrue(match, "Foundation.framework path located")
3541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("image dump symtab %s" % foundation_framework)
3641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        raw_output = self.res.GetOutput()
37609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # Now, grab every 'Code' symbol and feed it into the command:
38609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # 'disassemble -n func'.
39609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        #
40609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # The symbol name is on the last column and trails the flag column which
41609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits.
42609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        codeRE = re.compile(r"""
43609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             \ Code\ {9}    # ' Code' followed by 9 SPCs,
44609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             .*             # the wildcard chars,
45609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             0x[0-9a-f]{8}  # the flag column, and
46609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             \ (.+)$        # finally the function symbol.
47609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             """, re.VERBOSE)
4841998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        for line in raw_output.split(os.linesep):
49609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen            match = codeRE.search(line)
5041998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen            if match:
5141998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                func = match.group(1)
52a20392faaf3febd1b5e0a21a0a3c1ecfe71bb06eJohnny Chen                #print "line:", line
53a20392faaf3febd1b5e0a21a0a3c1ecfe71bb06eJohnny Chen                #print "func:", func
5441998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                self.runCmd('disassemble -n "%s"' % func)
5541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
5641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
57c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    def test_simple_disasm_with_dsym(self):
58c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        """Test the lldb 'disassemble' command"""
59c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.buildDsym()
60c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.do_simple_disasm()
61c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
62c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    def test_simple_disasm_with_dwarf(self):
63c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        """Test the lldb 'disassemble' command"""
64c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.buildDwarf()
65c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.do_simple_disasm()
66c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
67c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    def do_simple_disasm(self):
68c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        """Do a bunch of simple disassemble commands."""
69c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
70c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
71c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
72c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at +[NSString stringWithFormat:].
73b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton        self.expect("_regexp-break +[NSString stringWithFormat:]", BREAKPOINT_CREATED,
74018236c557f262a037a7e5073aebc4b80cecf77cJohnny Chen            substrs = ["Breakpoint created: 1: name = '+[NSString stringWithFormat:]', locations = 1"])
75c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
76c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at -[MyString initWithNSString:].
77c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("breakpoint set -n '-[MyString initWithNSString:]'", BREAKPOINT_CREATED,
78c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            startstr = "Breakpoint created: 2: name = '-[MyString initWithNSString:]', locations = 1")
79c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
80c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at the "description" selector.
81c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("breakpoint set -S description", BREAKPOINT_CREATED,
82c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            startstr = "Breakpoint created: 3: name = 'description', locations = 1")
83c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
84c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at -[NSAutoreleasePool release].
85b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton        self.expect("_regexp-break -[NSAutoreleasePool release]", BREAKPOINT_CREATED,
86018236c557f262a037a7e5073aebc4b80cecf77cJohnny Chen            substrs = ["Breakpoint created: 4: name = '-[NSAutoreleasePool release]', locations = 1"])
87c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
88c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
89c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
90c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # First stop is +[NSString stringWithFormat:].
91c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]",
92c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["Foundation`+[NSString stringWithFormat:]"])
93c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
94c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
9561c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
96c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
97c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("process continue")
98f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        # Skip another breakpoint for +[NSString stringWithFormat:].
99f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        self.runCmd("process continue")
100c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
101c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Followed by a.out`-[MyString initWithNSString:].
102c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]",
103c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["a.out`-[MyString initWithNSString:]"])
104c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
105c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
10661c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
107c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
108c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("process continue")
109c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
110c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Followed by -[MyString description].
111c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at -[MyString description]",
112c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["a.out`-[MyString description]"])
113c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
114c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
11561c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
116c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
117c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("process continue")
118f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        # Skip another breakpoint for -[MyString description].
119f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        self.runCmd("process continue")
120c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
121c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Followed by -[NSAutoreleasePool release].
122c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]",
123c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["Foundation`-[NSAutoreleasePool release]"])
124c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
125c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
12661c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
127c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
128c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
129c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenif __name__ == '__main__':
130c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    import atexit
131c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    lldb.SBDebugger.Initialize()
132c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
133c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    unittest2.main()
134