1c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham""" 2c4392dc344eb0c850dae74948bf249691ad9eb41Jim InghamTest calling a function that hits a signal set to auto-restart, make sure the call completes. 3c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham""" 4c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 5c4392dc344eb0c850dae74948bf249691ad9eb41Jim Inghamimport unittest2 6c4392dc344eb0c850dae74948bf249691ad9eb41Jim Inghamimport lldb 7c4392dc344eb0c850dae74948bf249691ad9eb41Jim Inghamimport lldbutil 8c4392dc344eb0c850dae74948bf249691ad9eb41Jim Inghamfrom lldbtest import * 9c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 10c4392dc344eb0c850dae74948bf249691ad9eb41Jim Inghamclass ExprCommandWithTimeoutsTestCase(TestBase): 11c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 12c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham mydir = os.path.join("expression_command", "call-restarts") 13c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 14c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham def setUp(self): 15c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Call super's setUp(). 16c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham TestBase.setUp(self) 17c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 18c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.main_source = "lotta-signals.c" 19c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.main_source_spec = lldb.SBFileSpec (self.main_source) 20c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 21c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 22c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 23c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham @dsym_test 24c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham def test_with_dsym(self): 25c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham """Test calling std::String member function.""" 26c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.buildDsym() 27c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.call_function() 28c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 296bc4dcdfbcdfa455299d2123011b82a77351ee72Daniel Malea @skipIfLinux # llvm.org/pr15278: handle expressions that generate signals on Linux 30c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham @dwarf_test 31c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham def test_with_dwarf(self): 32c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham """Test calling std::String member function.""" 33c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.buildDwarf() 34c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.call_function() 35c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 36c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham def check_after_call (self, num_sigchld): 37c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham after_call = self.sigchld_no.GetValueAsSigned(-1) 38c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (after_call - self.start_sigchld_no == num_sigchld, "Really got %d SIGCHLD signals through the call."%(num_sigchld)) 39c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.start_sigchld_no = after_call 40c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 41c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Check that we are back where we were before: 42c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham frame = self.thread.GetFrameAtIndex(0) 43c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (self.orig_frame_pc == frame.GetPC(), "Restored the zeroth frame correctly") 44c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 45c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 46c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham def call_function(self): 47c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham """Test calling function with timeout.""" 48c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham exe_name = "a.out" 49c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham exe = os.path.join(os.getcwd(), exe_name) 50c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 51c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham target = self.dbg.CreateTarget(exe) 52c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue(target, VALID_TARGET) 53c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham empty = lldb.SBFileSpec() 54c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham breakpoint = target.BreakpointCreateBySourceRegex('Stop here in main.',self.main_source_spec) 55c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT) 56c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 57c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Launch the process, and do not stop at the entry point. 58c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham process = target.LaunchSimple(None, None, os.getcwd()) 59c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 60c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue(process, PROCESS_IS_VALID) 61c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 62c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Frame #0 should be at our breakpoint. 63c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) 64c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 65c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue(len(threads) == 1) 66c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.thread = threads[0] 67c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 68c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Make sure the SIGCHLD behavior is pass/no-stop/no-notify: 69c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham return_obj = lldb.SBCommandReturnObject() 70c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 0", return_obj) 71c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop") 72c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 73c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # The sigchld_no variable should be 0 at this point. 74c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.sigchld_no = target.FindFirstGlobalVariable("sigchld_no") 75c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (self.sigchld_no.IsValid(), "Got a value for sigchld_no") 76c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 77c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.start_sigchld_no = self.sigchld_no.GetValueAsSigned (-1) 78c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (self.start_sigchld_no != -1, "Got an actual value for sigchld_no") 79c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 80c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham options = lldb.SBExpressionOptions() 81c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham options.SetUnwindOnError(True) 82c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 83c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham frame = self.thread.GetFrameAtIndex(0) 84c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Store away the PC to check that the functions unwind to the right place after calls 85c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.orig_frame_pc = frame.GetPC() 86c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 87c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham num_sigchld = 30 88c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham value = frame.EvaluateExpression ("call_me (%d)"%(num_sigchld), options) 89c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.IsValid()) 90c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.GetError().Success() == True) 91c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) 92c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 93c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.check_after_call(num_sigchld) 94c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 95c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Okay, now try with a breakpoint in the called code in the case where 96c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # we are ignoring breakpoint hits. 97c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham handler_bkpt = target.BreakpointCreateBySourceRegex("Got sigchld %d.", self.main_source_spec) 98c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (handler_bkpt.GetNumLocations() > 0) 99c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham options.SetIgnoreBreakpoints(True) 100c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham options.SetUnwindOnError(True) 101c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 102c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) 103c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 104c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.IsValid() and value.GetError().Success() == True) 105c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) 106c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.check_after_call(num_sigchld) 107c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 108c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Now set the signal to print but not stop and make sure that calling still works: 109c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj) 110c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify") 111c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 112c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) 113c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 114c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.IsValid() and value.GetError().Success() == True) 115c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) 116c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.check_after_call(num_sigchld) 117c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 118c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Now set this unwind on error to false, and make sure that we still complete the call: 119c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham options.SetUnwindOnError(False) 120c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) 121c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 122c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.IsValid() and value.GetError().Success() == True) 123c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) 124c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.check_after_call(num_sigchld) 125c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 126c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Okay, now set UnwindOnError to true, and then make the signal behavior to stop 127c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # and see that now we do stop at the signal point: 128c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 129c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 1 -p 1 -n 1", return_obj) 130c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, stop, notify") 131c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 132c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) 133c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (value.IsValid() and value.GetError().Success() == False) 134c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 135c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham # Set signal handling back to no-stop, and continue and we should end up back in out starting frame: 136c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj) 137c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify") 138c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 139c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham error = process.Continue() 140c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (error.Success(), "Continuing after stopping for signal succeeds.") 141c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 142c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham frame = self.thread.GetFrameAtIndex(0) 143c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham self.assertTrue (frame.GetPC() == self.orig_frame_pc, "Continuing returned to the place we started.") 144c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham 145c4392dc344eb0c850dae74948bf249691ad9eb41Jim Inghamif __name__ == '__main__': 146c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham import atexit 147c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham lldb.SBDebugger.Initialize() 148c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham atexit.register(lambda: lldb.SBDebugger.Terminate()) 149c4392dc344eb0c850dae74948bf249691ad9eb41Jim Ingham unittest2.main() 150