1from __future__ import print_function
2import lldb
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test.decorators import *
5from lldbsuite.test.gdbclientutils import *
6from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
7
8
9class TestRestartBug(GDBRemoteTestBase):
10
11    mydir = TestBase.compute_mydir(__file__)
12
13    @expectedFailureAll(bugnumber="llvm.org/pr24530")
14    def test(self):
15        """
16        Test auto-continue behavior when a process is interrupted to deliver
17        an "asynchronous" packet. This simulates the situation when a process
18        stops on its own just as lldb client is about to interrupt it. The
19        client should not auto-continue in this case, unless the user has
20        explicitly requested that we ignore signals of this type.
21        """
22        class MyResponder(MockGDBServerResponder):
23            continueCount = 0
24
25            def setBreakpoint(self, packet):
26                return "OK"
27
28            def interrupt(self):
29                # Simulate process stopping due to a raise(SIGINT) just as lldb
30                # is about to interrupt it.
31                return "T02reason:signal"
32
33            def cont(self):
34                self.continueCount += 1
35                if self.continueCount == 1:
36                    # No response, wait for the client to interrupt us.
37                    return None
38                return "W00" # Exit
39
40        self.server.responder = MyResponder()
41        target = self.createTarget("a.yaml")
42        process = self.connect(target)
43        self.dbg.SetAsync(True)
44        process.Continue()
45
46        # resume the process and immediately try to set another breakpoint. When using the remote
47        # stub, this will trigger a request to stop the process.  Make sure we
48        # do not lose this signal.
49        bkpt = target.BreakpointCreateByAddress(0x1234)
50        self.assertTrue(bkpt.IsValid())
51        self.assertEqual(bkpt.GetNumLocations(), 1)
52
53        event = lldb.SBEvent()
54        while self.dbg.GetListener().WaitForEvent(2, event):
55            if self.TraceOn():
56                print("Process changing state to:",
57                    self.dbg.StateAsCString(process.GetStateFromEvent(event)))
58            if process.GetStateFromEvent(event) == lldb.eStateExited:
59                break
60
61        # We should get only one continue packet as the client should not
62        # auto-continue after setting the breakpoint.
63        self.assertEqual(self.server.responder.continueCount, 1)
64        # And the process should end up in the stopped state.
65        self.assertState(process.GetState(), lldb.eStateStopped)
66