brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · a108ffe Raw
141 lines · python
1"""2Test calling a function that hits a signal set to auto-restart, make sure the call completes.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class ExprCommandThatRestartsTestCase(TestBase):13    NO_DEBUG_INFO_TESTCASE = True14 15    def setUp(self):16        # Call super's setUp().17        TestBase.setUp(self)18 19        self.main_source = "lotta-signals.c"20        self.main_source_spec = lldb.SBFileSpec(self.main_source)21 22    @skipIfDarwin  # llvm.org/pr19246: intermittent failure23    @skipIfWindows  # Test relies on signals, unsupported on Windows24    @expectedFlakeyAndroid(bugnumber="llvm.org/pr19246")25    @expectedFlakeyNetBSD26    def test(self):27        """Test calling function that hits a signal and restarts."""28        self.build()29        self.call_function()30 31    def check_after_call(self, num_sigchld):32        after_call = self.sigchld_no.GetValueAsSigned(-1)33        self.assertEqual(34            after_call - self.start_sigchld_no,35            num_sigchld,36            "Really got %d SIGCHLD signals through the call." % (num_sigchld),37        )38        self.start_sigchld_no = after_call39 40        # Check that we are back where we were before:41        frame = self.thread.GetFrameAtIndex(0)42        self.assertEqual(43            self.orig_frame_pc, frame.GetPC(), "Restored the zeroth frame correctly"44        )45 46    def call_function(self):47        (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(48            self, "Stop here in main.", self.main_source_spec49        )50 51        # Make sure the SIGCHLD behavior is pass/no-stop/no-notify:52        self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 0")53 54        # The sigchld_no variable should be 0 at this point.55        self.sigchld_no = target.FindFirstGlobalVariable("sigchld_no")56        self.assertTrue(self.sigchld_no.IsValid(), "Got a value for sigchld_no")57 58        self.start_sigchld_no = self.sigchld_no.GetValueAsSigned(-1)59        self.assertNotEqual(60            self.start_sigchld_no, -1, "Got an actual value for sigchld_no"61        )62 63        options = lldb.SBExpressionOptions()64        # processing 30 signals takes a while, increase the expression timeout65        # a bit66        options.SetTimeoutInMicroSeconds(3000000)  # 3s67        options.SetUnwindOnError(True)68 69        frame = self.thread.GetFrameAtIndex(0)70        # Store away the PC to check that the functions unwind to the right71        # place after calls72        self.orig_frame_pc = frame.GetPC()73 74        num_sigchld = 3075        value = frame.EvaluateExpression("call_me (%d)" % (num_sigchld), options)76        self.assertTrue(value.IsValid())77        self.assertSuccess(value.GetError())78        self.assertEqual(value.GetValueAsSigned(-1), num_sigchld)79 80        self.check_after_call(num_sigchld)81 82        # Okay, now try with a breakpoint in the called code in the case where83        # we are ignoring breakpoint hits.84        handler_bkpt = target.BreakpointCreateBySourceRegex(85            "Got sigchld %d.", self.main_source_spec86        )87        self.assertGreater(handler_bkpt.GetNumLocations(), 0)88        options.SetIgnoreBreakpoints(True)89        options.SetUnwindOnError(True)90 91        value = frame.EvaluateExpression("call_me (%d)" % (num_sigchld), options)92 93        self.assertTrue(value.IsValid())94        self.assertSuccess(value.GetError())95        self.assertEqual(value.GetValueAsSigned(-1), num_sigchld)96        self.check_after_call(num_sigchld)97 98        # Now set the signal to print but not stop and make sure that calling99        # still works:100        self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 1")101 102        value = frame.EvaluateExpression("call_me (%d)" % (num_sigchld), options)103 104        self.assertTrue(value.IsValid())105        self.assertSuccess(value.GetError())106        self.assertEqual(value.GetValueAsSigned(-1), num_sigchld)107        self.check_after_call(num_sigchld)108 109        # Now set this unwind on error to false, and make sure that we still110        # complete the call:111        options.SetUnwindOnError(False)112        value = frame.EvaluateExpression("call_me (%d)" % (num_sigchld), options)113 114        self.assertTrue(value.IsValid())115        self.assertSuccess(value.GetError())116        self.assertEqual(value.GetValueAsSigned(-1), num_sigchld)117        self.check_after_call(num_sigchld)118 119        # Okay, now set UnwindOnError to true, and then make the signal behavior to stop120        # and see that now we do stop at the signal point:121 122        self.runCmd("process handle SIGCHLD -s 1 -p 1 -n 1")123 124        value = frame.EvaluateExpression("call_me (%d)" % (num_sigchld), options)125        self.assertTrue(value.IsValid())126        self.assertFalse(value.GetError().Success())127 128        # Set signal handling back to no-stop, and continue and we should end129        # up back in out starting frame:130        self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 1")131 132        error = process.Continue()133        self.assertSuccess(error, "Continuing after stopping for signal succeeds.")134 135        frame = self.thread.GetFrameAtIndex(0)136        self.assertEqual(137            frame.GetPC(),138            self.orig_frame_pc,139            "Continuing returned to the place we started.",140        )141