Home | History | Annotate | Download | only in inferior-assert
      1 """Test that lldb functions correctly after the inferior has asserted."""
      2 
      3 import os, time
      4 import unittest2
      5 import lldb, lldbutil
      6 from lldbtest import *
      7 
      8 class AssertingInferiorTestCase(TestBase):
      9 
     10     mydir = os.path.join("functionalities", "inferior-assert")
     11 
     12     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     13     def test_inferior_asserting_dsym(self):
     14         """Test that lldb reliably catches the inferior asserting (command)."""
     15         self.buildDsym()
     16         self.inferior_asserting()
     17 
     18     def test_inferior_asserting_dwarf(self):
     19         """Test that lldb reliably catches the inferior asserting (command)."""
     20         self.buildDwarf()
     21         self.inferior_asserting()
     22 
     23     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     24     def test_inferior_asserting_registers_dsym(self):
     25         """Test that lldb reliably reads registers from the inferior after asserting (command)."""
     26         self.buildDsym()
     27         self.inferior_asserting_registers()
     28 
     29     def test_inferior_asserting_register_dwarf(self):
     30         """Test that lldb reliably reads registers from the inferior after asserting (command)."""
     31         self.buildDwarf()
     32         self.inferior_asserting_registers()
     33 
     34     @skipIfGcc # Avoid xpasses as the verion of libc used on the gcc buildbot has the required function symbols.
     35     @expectedFailureLinux # ResolveSymbolContextForAddress can fail using ELF with stripped function symbols.
     36     def test_inferior_asserting_disassemble(self):
     37         """Test that lldb reliably disassemblers frames after asserting (command)."""
     38         self.buildDefault()
     39         self.inferior_asserting_disassemble()
     40 
     41     @python_api_test
     42     def test_inferior_asserting_python(self):
     43         """Test that lldb reliably catches the inferior asserting (Python API)."""
     44         self.buildDefault()
     45         self.inferior_asserting_python()
     46 
     47     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     48     def test_inferior_asserting_expr(self):
     49         """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
     50         self.buildDsym()
     51         self.inferior_asserting_expr()
     52 
     53     def test_inferior_asserting_expr(self):
     54         """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
     55         self.buildDwarf()
     56         self.inferior_asserting_expr()
     57 
     58     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     59     def test_inferior_asserting_step(self):
     60         """Test that lldb functions correctly after stepping through a call to assert()."""
     61         self.buildDsym()
     62         self.inferior_asserting_step()
     63 
     64     def test_inferior_asserting_step(self):
     65         """Test that lldb functions correctly after stepping through a call to assert()."""
     66         self.buildDwarf()
     67         self.inferior_asserting_step()
     68 
     69     def set_breakpoint(self, line):
     70         lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
     71 
     72     def check_stop_reason(self):
     73         stop_reason = 'stop reason = signal SIGABRT'
     74 
     75         # The stop reason of the thread should be an abort signal or exception.
     76         self.expect("thread list", STOPPED_DUE_TO_ASSERT,
     77             substrs = ['stopped',
     78                        stop_reason])
     79 
     80         return stop_reason
     81 
     82     def setUp(self):
     83         # Call super's setUp().
     84         TestBase.setUp(self)
     85         # Find the line number of the call to assert.
     86         self.line = line_number('main.c', '// Assert here.')
     87 
     88     def inferior_asserting(self):
     89         """Inferior asserts upon launching; lldb should catch the event and stop."""
     90         exe = os.path.join(os.getcwd(), "a.out")
     91         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     92 
     93         self.runCmd("run", RUN_SUCCEEDED)
     94         stop_reason = self.check_stop_reason()
     95 
     96         # And it should report a backtrace that includes the assert site.
     97         self.expect("thread backtrace all",
     98             substrs = [stop_reason, 'main', 'argc', 'argv'])
     99 
    100         # And it should report the correct line number.
    101         self.expect("thread backtrace all",
    102             substrs = [stop_reason,
    103                        'main.c:%d' % self.line])
    104 
    105     def inferior_asserting_python(self):
    106         """Inferior asserts upon launching; lldb should catch the event and stop."""
    107         exe = os.path.join(os.getcwd(), "a.out")
    108 
    109         target = self.dbg.CreateTarget(exe)
    110         self.assertTrue(target, VALID_TARGET)
    111 
    112         # Now launch the process, and do not stop at entry point.
    113         # Both argv and envp are null.
    114         process = target.LaunchSimple(None, None, os.getcwd())
    115 
    116         if process.GetState() != lldb.eStateStopped:
    117             self.fail("Process should be in the 'stopped' state, "
    118                       "instead the actual state is: '%s'" %
    119                       lldbutil.state_type_to_str(process.GetState()))
    120 
    121         thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
    122         if not thread:
    123             self.fail("Fail to stop the thread upon assert")
    124 
    125         if self.TraceOn():
    126             lldbutil.print_stacktrace(thread)
    127 
    128     def inferior_asserting_registers(self):
    129         """Test that lldb can read registers after asserting."""
    130         exe = os.path.join(os.getcwd(), "a.out")
    131         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
    132 
    133         self.runCmd("run", RUN_SUCCEEDED)
    134         self.check_stop_reason()
    135 
    136         # lldb should be able to read from registers from the inferior after asserting.
    137         self.expect("register read eax",
    138             substrs = ['eax = 0x'])
    139 
    140     def inferior_asserting_disassemble(self):
    141         """Test that lldb can disassemble frames after asserting."""
    142         exe = os.path.join(os.getcwd(), "a.out")
    143 
    144         # Create a target by the debugger.
    145         target = self.dbg.CreateTarget(exe)
    146         self.assertTrue(target, VALID_TARGET)
    147 
    148         # Launch the process, and do not stop at the entry point.
    149         target.LaunchSimple(None, None, os.getcwd())
    150         self.check_stop_reason()
    151 
    152         process = target.GetProcess()
    153         self.assertTrue(process.IsValid(), "current process is valid")
    154 
    155         thread = process.GetThreadAtIndex(0)
    156         self.assertTrue(thread.IsValid(), "current thread is valid")
    157 
    158         # lldb should be able to disassemble frames from the inferior after asserting.
    159         for frame in thread:
    160             self.assertTrue(frame.IsValid(), "current frame is valid")
    161 
    162             self.runCmd("frame select " + str(frame.GetFrameID()), RUN_SUCCEEDED)
    163 
    164             self.expect("disassemble -a %s" % frame.GetPC(),
    165                 substrs = ['->', frame.GetFunctionName()])
    166 
    167     def check_expr_in_main(self, thread):
    168         depth = thread.GetNumFrames()
    169         for i in range(depth):
    170             frame = thread.GetFrameAtIndex(i)
    171             self.assertTrue(frame.IsValid(), "current frame is valid")
    172             if self.TraceOn():
    173                 print "Checking if function %s is main" % frame.GetFunctionName()
    174 
    175             if 'main' == frame.GetFunctionName():
    176                 frame_id = frame.GetFrameID()
    177                 self.runCmd("frame select " + str(frame_id), RUN_SUCCEEDED)
    178                 self.expect("p argc", substrs = ['(int)', ' = 1'])
    179                 self.expect("p hello_world", substrs = ['Hello'])
    180                 self.expect("p argv[0]", substrs = ['a.out'])
    181                 self.expect("p null_ptr", substrs = ['= 0x0'])
    182                 return True 
    183         return False 
    184 
    185     def inferior_asserting_expr(self):
    186         """Test that the lldb expression interpreter can read symbols after asserting."""
    187         exe = os.path.join(os.getcwd(), "a.out")
    188 
    189         # Create a target by the debugger.
    190         target = self.dbg.CreateTarget(exe)
    191         self.assertTrue(target, VALID_TARGET)
    192 
    193         # Launch the process, and do not stop at the entry point.
    194         target.LaunchSimple(None, None, os.getcwd())
    195         self.check_stop_reason()
    196 
    197         process = target.GetProcess()
    198         self.assertTrue(process.IsValid(), "current process is valid")
    199 
    200         thread = process.GetThreadAtIndex(0)
    201         self.assertTrue(thread.IsValid(), "current thread is valid")
    202 
    203         # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
    204         self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
    205 
    206     def inferior_asserting_step(self):
    207         """Test that lldb functions correctly after stepping through a call to assert()."""
    208         exe = os.path.join(os.getcwd(), "a.out")
    209 
    210         # Create a target by the debugger.
    211         target = self.dbg.CreateTarget(exe)
    212         self.assertTrue(target, VALID_TARGET)
    213 
    214         # Launch the process, and do not stop at the entry point.
    215         self.set_breakpoint(self.line)
    216         target.LaunchSimple(None, None, os.getcwd())
    217 
    218         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    219             substrs = ['main.c:%d' % self.line,
    220                        'stop reason = breakpoint'])
    221 
    222         self.runCmd("next")
    223         stop_reason = self.check_stop_reason()
    224 
    225         # lldb should be able to read from registers from the inferior after asserting.
    226         if "x86_64" in self.getArchitecture():
    227             self.expect("register read rbp", substrs = ['rbp = 0x'])
    228         if "i386" in self.getArchitecture():
    229             self.expect("register read ebp", substrs = ['ebp = 0x'])
    230 
    231         process = target.GetProcess()
    232         self.assertTrue(process.IsValid(), "current process is valid")
    233 
    234         thread = process.GetThreadAtIndex(0)
    235         self.assertTrue(thread.IsValid(), "current thread is valid")
    236 
    237         # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
    238         self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
    239 
    240         # And it should report the correct line number.
    241         self.expect("thread backtrace all",
    242             substrs = [stop_reason,
    243                        'main.c:%d' % self.line])
    244 
    245 if __name__ == '__main__':
    246     import atexit
    247     lldb.SBDebugger.Initialize()
    248     atexit.register(lambda: lldb.SBDebugger.Terminate())
    249     unittest2.main()
    250