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 *
9431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
10c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
11c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
12c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenclass FoundationDisassembleTestCase(TestBase):
13c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
14b8025be2976a40d072e9a6d4eb7c9316d65bb16eJohnny Chen    mydir = os.path.join("lang", "objc", "foundation")
15c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
1641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    # rdar://problem/8504895
1741998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]"
1841998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
1941998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen    def test_foundation_disasm(self):
2041998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        """Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework."""
2141998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.buildDefault()
2241998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
2341998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
2441998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
2541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
2641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("image list")
2741998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        raw_output = self.res.GetOutput()
2841998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        # Grok the full path to the foundation framework.
2941998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        for line in raw_output.split(os.linesep):
3041998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen            match = re.search(" (/.*/Foundation.framework/.*)$", line)
3141998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen            if match:
3241998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                foundation_framework = match.group(1)
3341998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                break
3441998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
3541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.assertTrue(match, "Foundation.framework path located")
3641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        self.runCmd("image dump symtab %s" % foundation_framework)
3741998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        raw_output = self.res.GetOutput()
38609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # Now, grab every 'Code' symbol and feed it into the command:
39609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # 'disassemble -n func'.
40609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        #
41609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # The symbol name is on the last column and trails the flag column which
42609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits.
43609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen        codeRE = re.compile(r"""
44609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             \ Code\ {9}    # ' Code' followed by 9 SPCs,
45609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             .*             # the wildcard chars,
46609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             0x[0-9a-f]{8}  # the flag column, and
47609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             \ (.+)$        # finally the function symbol.
48609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen                             """, re.VERBOSE)
4941998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen        for line in raw_output.split(os.linesep):
50609fb486b1a69aa488571cac9125907ef9e55cdbJohnny Chen            match = codeRE.search(line)
5141998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen            if match:
5241998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                func = match.group(1)
53a20392faaf3febd1b5e0a21a0a3c1ecfe71bb06eJohnny Chen                #print "line:", line
54a20392faaf3febd1b5e0a21a0a3c1ecfe71bb06eJohnny Chen                #print "func:", func
5541998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen                self.runCmd('disassemble -n "%s"' % func)
5641998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
5741998197e9d81cba31ac4645c1ec5f0ba7ca1668Johnny Chen
5821b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
59c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    def test_simple_disasm_with_dsym(self):
60c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        """Test the lldb 'disassemble' command"""
61c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.buildDsym()
62c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.do_simple_disasm()
63c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
6421b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
65c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    def test_simple_disasm_with_dwarf(self):
66c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        """Test the lldb 'disassemble' command"""
67c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.buildDwarf()
68c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.do_simple_disasm()
69c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
70c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    def do_simple_disasm(self):
71c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        """Do a bunch of simple disassemble commands."""
72c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
73c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
74c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
75c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at +[NSString stringWithFormat:].
76431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        symbol_name = "+[NSString stringWithFormat:]"
77431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        break_results = lldbutil.run_break_set_command (self, "_regexp-break %s"%(symbol_name))
78431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.check_breakpoint_result (self, break_results, symbol_name=symbol_name, num_locations=1)
79c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
80c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at -[MyString initWithNSString:].
81431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True)
82c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
83c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at the "description" selector.
842fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out')
85c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
86c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Stop at -[NSAutoreleasePool release].
87431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        break_results = lldbutil.run_break_set_command (self, "_regexp-break -[NSAutoreleasePool release]")
88431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.check_breakpoint_result (self, break_results, symbol_name='-[NSAutoreleasePool release]', num_locations=1)
89c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
90c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
91c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
92c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # First stop is +[NSString stringWithFormat:].
93c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]",
94c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["Foundation`+[NSString stringWithFormat:]"])
95c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
96c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
9761c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
98c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
99c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("process continue")
100f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        # Skip another breakpoint for +[NSString stringWithFormat:].
101f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        self.runCmd("process continue")
102c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
103c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Followed by a.out`-[MyString initWithNSString:].
104c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]",
105c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["a.out`-[MyString initWithNSString:]"])
106c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
107c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
10861c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
109c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
110c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("process continue")
111c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
112c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Followed by -[MyString description].
113c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at -[MyString description]",
114c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["a.out`-[MyString description]"])
115c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
116c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
11761c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
118c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
119c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.runCmd("process continue")
120f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        # Skip another breakpoint for -[MyString description].
121f9954b5db8e58d83580233e442e7344b3c01280aJohnny Chen        self.runCmd("process continue")
122c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
123c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Followed by -[NSAutoreleasePool release].
124c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]",
125c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen            substrs = ["Foundation`-[NSAutoreleasePool release]"])
126c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
127c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen        # Do the disassemble for the currently stopped function.
12861c1b8be0532dbd06317ef4c5c4f3e4c4268f13fJohnny Chen        self.runCmd("disassemble -f")
129c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
130c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen
131c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chenif __name__ == '__main__':
132c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    import atexit
133c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    lldb.SBDebugger.Initialize()
134c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
135c3bfbd18b6210065a0763c48b5f7b7d4d9582de6Johnny Chen    unittest2.main()
136