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