1"""Test lldb reloads the inferior after it was changed during the session.""" 2 3import os, time 4import unittest2 5import lldb 6from lldbtest import * 7import lldbutil 8 9class 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 98if __name__ == '__main__': 99 import atexit 100 lldb.SBDebugger.Initialize() 101 atexit.register(lambda: lldb.SBDebugger.Terminate()) 102 unittest2.main() 103