Home | History | Annotate | Download | only in foundation
      1 """
      2 Test the lldb disassemble command on foundation framework.
      3 """
      4 
      5 import os, time
      6 import unittest2
      7 import lldb
      8 from lldbtest import *
      9 import lldbutil
     10 
     11 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     12 class FoundationDisassembleTestCase(TestBase):
     13 
     14     mydir = os.path.join("lang", "objc", "foundation")
     15 
     16     # rdar://problem/8504895
     17     # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]"
     18     @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
     19     def test_foundation_disasm(self):
     20         """Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework."""
     21         self.buildDefault()
     22         exe = os.path.join(os.getcwd(), "a.out")
     23         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     24         self.runCmd("run", RUN_SUCCEEDED)
     25 
     26         self.runCmd("image list")
     27         raw_output = self.res.GetOutput()
     28         # Grok the full path to the foundation framework.
     29         for line in raw_output.split(os.linesep):
     30             match = re.search(" (/.*/Foundation.framework/.*)$", line)
     31             if match:
     32                 foundation_framework = match.group(1)
     33                 break
     34 
     35         self.assertTrue(match, "Foundation.framework path located")
     36         self.runCmd("image dump symtab %s" % foundation_framework)
     37         raw_output = self.res.GetOutput()
     38         # Now, grab every 'Code' symbol and feed it into the command:
     39         # 'disassemble -n func'.
     40         #
     41         # The symbol name is on the last column and trails the flag column which
     42         # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits.
     43         codeRE = re.compile(r"""
     44                              \ Code\ {9}    # ' Code' followed by 9 SPCs,
     45                              .*             # the wildcard chars,
     46                              0x[0-9a-f]{8}  # the flag column, and
     47                              \ (.+)$        # finally the function symbol.
     48                              """, re.VERBOSE)
     49         for line in raw_output.split(os.linesep):
     50             match = codeRE.search(line)
     51             if match:
     52                 func = match.group(1)
     53                 #print "line:", line
     54                 #print "func:", func
     55                 self.runCmd('disassemble -n "%s"' % func)
     56         
     57 
     58     @dsym_test
     59     def test_simple_disasm_with_dsym(self):
     60         """Test the lldb 'disassemble' command"""
     61         self.buildDsym()
     62         self.do_simple_disasm()
     63 
     64     @dwarf_test
     65     def test_simple_disasm_with_dwarf(self):
     66         """Test the lldb 'disassemble' command"""
     67         self.buildDwarf()
     68         self.do_simple_disasm()
     69 
     70     def do_simple_disasm(self):
     71         """Do a bunch of simple disassemble commands."""
     72         exe = os.path.join(os.getcwd(), "a.out")
     73         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     74 
     75         # Stop at +[NSString stringWithFormat:].
     76         symbol_name = "+[NSString stringWithFormat:]"
     77         break_results = lldbutil.run_break_set_command (self, "_regexp-break %s"%(symbol_name))
     78         lldbutil.check_breakpoint_result (self, break_results, symbol_name=symbol_name, num_locations=1)
     79 
     80         # Stop at -[MyString initWithNSString:].
     81         lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True)
     82 
     83         # Stop at the "description" selector.
     84         lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out')
     85 
     86         # Stop at -[NSAutoreleasePool release].
     87         break_results = lldbutil.run_break_set_command (self, "_regexp-break -[NSAutoreleasePool release]")
     88         lldbutil.check_breakpoint_result (self, break_results, symbol_name='-[NSAutoreleasePool release]', num_locations=1)
     89 
     90         self.runCmd("run", RUN_SUCCEEDED)
     91 
     92         # First stop is +[NSString stringWithFormat:].
     93         self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]",
     94             substrs = ["Foundation`+[NSString stringWithFormat:]"])
     95 
     96         # Do the disassemble for the currently stopped function.
     97         self.runCmd("disassemble -f")
     98 
     99         self.runCmd("process continue")
    100         # Skip another breakpoint for +[NSString stringWithFormat:].
    101         self.runCmd("process continue")
    102 
    103         # Followed by a.out`-[MyString initWithNSString:].
    104         self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]",
    105             substrs = ["a.out`-[MyString initWithNSString:]"])
    106 
    107         # Do the disassemble for the currently stopped function.
    108         self.runCmd("disassemble -f")
    109 
    110         self.runCmd("process continue")
    111 
    112         # Followed by -[MyString description].
    113         self.expect("thread backtrace", "Stop at -[MyString description]",
    114             substrs = ["a.out`-[MyString description]"])
    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 -[MyString description].
    121         self.runCmd("process continue")
    122 
    123         # Followed by -[NSAutoreleasePool release].
    124         self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]",
    125             substrs = ["Foundation`-[NSAutoreleasePool release]"])
    126 
    127         # Do the disassemble for the currently stopped function.
    128         self.runCmd("disassemble -f")
    129 
    130 
    131 if __name__ == '__main__':
    132     import atexit
    133     lldb.SBDebugger.Initialize()
    134     atexit.register(lambda: lldb.SBDebugger.Terminate())
    135     unittest2.main()
    136