Home | History | Annotate | Download | only in inferior-changed
      1 """Test lldb reloads the inferior after it was changed during the session."""
      2 
      3 import os, time
      4 import unittest2
      5 import lldb
      6 from lldbtest import *
      7 import lldbutil
      8 
      9 class ChangedInferiorTestCase(TestBase):
     10 
     11     mydir = os.path.join("functionalities", "inferior-changed")
     12 
     13     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     14     def test_inferior_crashing_dsym(self):
     15         """Test lldb reloads the inferior after it was changed during the session."""
     16         self.buildDsym()
     17         self.inferior_crashing()
     18         self.cleanup()
     19         d = {'C_SOURCES': 'main2.c'}
     20         self.buildDsym(dictionary=d)
     21         self.setTearDownCleanup(dictionary=d)
     22         self.inferior_not_crashing()
     23 
     24     def test_inferior_crashing_dwarf(self):
     25         """Test lldb reloads the inferior after it was changed during the session."""
     26         self.buildDwarf()
     27         self.inferior_crashing()
     28         self.cleanup()
     29         # lldb needs to recognize the inferior has changed. If lldb needs to check the
     30         # new module timestamp, make sure it is not the same as the old one, so add a
     31         # 1 second delay.
     32         time.sleep(1)
     33         d = {'C_SOURCES': 'main2.c'}
     34         self.buildDwarf(dictionary=d)
     35         self.setTearDownCleanup(dictionary=d)
     36         self.inferior_not_crashing()
     37 
     38     def setUp(self):
     39         # Call super's setUp().
     40         TestBase.setUp(self)
     41         # Find the line number of the crash.
     42         self.line1 = line_number('main.c', '// Crash here.')
     43         self.line2 = line_number('main2.c', '// Not crash here.')
     44 
     45     def inferior_crashing(self):
     46         """Inferior crashes upon launching; lldb should catch the event and stop."""
     47         exe = os.path.join(os.getcwd(), "a.out")
     48         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     49 
     50         self.runCmd("run", RUN_SUCCEEDED)
     51 
     52         if sys.platform.startswith("darwin"):
     53             stop_reason = 'stop reason = EXC_BAD_ACCESS'
     54         else:
     55             stop_reason = 'stop reason = invalid address'
     56 
     57         # The stop reason of the thread should be a bad access exception.
     58         self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
     59             substrs = ['stopped',
     60                        stop_reason])
     61 
     62         # And it should report the correct line number.
     63         self.expect("thread backtrace all",
     64             substrs = [stop_reason,
     65                        'main.c:%d' % self.line1])
     66 
     67     def inferior_not_crashing(self):
     68         """Test lldb reloads the inferior after it was changed during the session."""
     69         self.runCmd("process kill")
     70         self.runCmd("run", RUN_SUCCEEDED)
     71         self.runCmd("process status")
     72 
     73         if sys.platform.startswith("darwin"):
     74             stop_reason = 'EXC_BAD_ACCESS'
     75         else:
     76             stop_reason = 'invalid address'
     77 
     78         if stop_reason in self.res.GetOutput():
     79             self.fail("Inferior changed, but lldb did not perform a reload")
     80 
     81         # Break inside the main.
     82         lldbutil.run_break_set_by_file_and_line (self, "main2.c", self.line2, num_expected_locations=1, loc_exact=True)
     83 
     84         self.runCmd("run", RUN_SUCCEEDED)
     85 
     86         # The stop reason of the thread should be breakpoint.
     87         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
     88             substrs = ['stopped',
     89                        'stop reason = breakpoint'])
     90 
     91         self.runCmd("frame variable int_ptr")
     92         self.expect("frame variable *int_ptr",
     93             substrs = ['= 7'])
     94         self.expect("expression *int_ptr",
     95             substrs = ['= 7'])
     96 
     97 
     98 if __name__ == '__main__':
     99     import atexit
    100     lldb.SBDebugger.Initialize()
    101     atexit.register(lambda: lldb.SBDebugger.Terminate())
    102     unittest2.main()
    103