135 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
| """
 | |
| Test the lldb disassemble command on foundation framework.
 | |
| """
 | |
| 
 | |
| from __future__ import print_function
 | |
| 
 | |
| 
 | |
| 
 | |
| import unittest2
 | |
| import os, time
 | |
| import lldb
 | |
| from lldbsuite.test.lldbtest import *
 | |
| import lldbsuite.test.lldbutil as 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("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 != 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("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")
 |