1d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen"""Test that lldb command 'process signal SIGUSR1' to send a signal to the inferior works."""
2d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
3d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chenimport os, time, signal
4d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chenimport unittest2
5d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chenimport lldb
6d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chenfrom lldbtest import *
7431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
8d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
9d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chenclass SendSignalTestCase(TestBase):
10d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
11e2ac6dec08024429fcc8ef1646a435a732e5e94dJohnny Chen    mydir = os.path.join("functionalities", "signal")
12d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
13d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
14a3ed7d834b0e0c6924ac95629e740682bbcd15baJohnny Chen    @dsym_test
15d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    def test_with_dsym_and_run_command(self):
16d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process."""
17d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.buildDsym()
18d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.send_signal()
19d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
20a3ed7d834b0e0c6924ac95629e740682bbcd15baJohnny Chen    @dwarf_test
21d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    def test_with_dwarf_and_run_command(self):
22d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process."""
23d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.buildDwarf()
24d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.send_signal()
25d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
26d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    def setUp(self):
270910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        # Call super's setUp().
280910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        TestBase.setUp(self)
29d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        # Find the line number to break inside main().
30d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.line = line_number('main.c', 'Put breakpoint here')
31d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
32d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    def send_signal(self):
33d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process."""
34d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
35d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        exe = os.path.join(os.getcwd(), "a.out")
36d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
37d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
38d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        # Break inside the main() function and immediately send a signal to the inferior after resuming.
39431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
40d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
41d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.runCmd("run", RUN_SUCCEEDED)
42c418ec28f83f9bc3b09837d255c903f587c43e92Johnny Chen        self.runCmd("thread backtrace")
43d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
44d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        # The stop reason of the thread should be breakpoint.
45d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
46abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton            substrs = ['stopped',
47d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen                       'stop reason = breakpoint'])
48d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
49d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        # The breakpoint should have a hit count of 1.
5041950cc77813637e6c67b069e4ad2faf8c5f6fa7Caroline Tice        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
51d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen            substrs = [' resolved, hit count = 1'])
52d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
53d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.runCmd("process status")
54d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        output = self.res.GetOutput()
558a87d5244a61570e06f9b48b9bc04773e82e301eJohnny Chen        pid = re.match("Process (.*) stopped", output).group(1)
56d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
575b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # After resuming the process, send it a SIGUSR1 signal.
585b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen
595b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # It is necessary at this point to make command interpreter interaction
605b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # be asynchronous, because we want to resume the process and to send it
615b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # a signal.
62d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.dbg.SetAsync(True)
63d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.runCmd("process continue")
645b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # Insert a delay of 1 second before doing the signaling stuffs.
655b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        time.sleep(1)
665b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen
67d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.runCmd("process handle -n False -p True -s True SIGUSR1")
68d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        #os.kill(int(pid), signal.SIGUSR1)
69d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.runCmd("process signal SIGUSR1")
70d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
715b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # Insert a delay of 1 second before checking the process status.
72d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        time.sleep(1)
735b33af2605f4589038ad0612a5675ff023e7d53fJohnny Chen        # Make the interaction mode be synchronous again.
74d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.dbg.SetAsync(False)
75d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.expect("process status", STOPPED_DUE_TO_SIGNAL,
768a87d5244a61570e06f9b48b9bc04773e82e301eJohnny Chen            startstr = "Process %s stopped" % pid,
77d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen            substrs = ['stop reason = signal SIGUSR1'])
78d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen        self.expect("thread backtrace", STOPPED_DUE_TO_SIGNAL,
79d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen            substrs = ['stop reason = signal SIGUSR1'])
80d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
81d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen
82d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chenif __name__ == '__main__':
83d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    import atexit
84d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    lldb.SBDebugger.Initialize()
85d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
86d7a4eb073d08bf632154b74189e36a28726cefaaJohnny Chen    unittest2.main()
87