199451b44SJordan Rupprechtfrom __future__ import print_function
299451b44SJordan Rupprechtimport lldb
399451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
499451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
533c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
633c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
799451b44SJordan Rupprecht
899451b44SJordan Rupprecht
999451b44SJordan Rupprechtclass TestRestartBug(GDBRemoteTestBase):
1099451b44SJordan Rupprecht
1199451b44SJordan Rupprecht    @expectedFailureAll(bugnumber="llvm.org/pr24530")
1299451b44SJordan Rupprecht    def test(self):
1399451b44SJordan Rupprecht        """
1499451b44SJordan Rupprecht        Test auto-continue behavior when a process is interrupted to deliver
1599451b44SJordan Rupprecht        an "asynchronous" packet. This simulates the situation when a process
1699451b44SJordan Rupprecht        stops on its own just as lldb client is about to interrupt it. The
1799451b44SJordan Rupprecht        client should not auto-continue in this case, unless the user has
1899451b44SJordan Rupprecht        explicitly requested that we ignore signals of this type.
1999451b44SJordan Rupprecht        """
2099451b44SJordan Rupprecht        class MyResponder(MockGDBServerResponder):
2199451b44SJordan Rupprecht            continueCount = 0
2299451b44SJordan Rupprecht
2399451b44SJordan Rupprecht            def setBreakpoint(self, packet):
2499451b44SJordan Rupprecht                return "OK"
2599451b44SJordan Rupprecht
2699451b44SJordan Rupprecht            def interrupt(self):
2799451b44SJordan Rupprecht                # Simulate process stopping due to a raise(SIGINT) just as lldb
2899451b44SJordan Rupprecht                # is about to interrupt it.
2999451b44SJordan Rupprecht                return "T02reason:signal"
3099451b44SJordan Rupprecht
3199451b44SJordan Rupprecht            def cont(self):
3299451b44SJordan Rupprecht                self.continueCount += 1
3399451b44SJordan Rupprecht                if self.continueCount == 1:
3499451b44SJordan Rupprecht                    # No response, wait for the client to interrupt us.
3599451b44SJordan Rupprecht                    return None
3699451b44SJordan Rupprecht                return "W00" # Exit
3799451b44SJordan Rupprecht
3899451b44SJordan Rupprecht        self.server.responder = MyResponder()
3999451b44SJordan Rupprecht        target = self.createTarget("a.yaml")
4099451b44SJordan Rupprecht        process = self.connect(target)
4199451b44SJordan Rupprecht        self.dbg.SetAsync(True)
4299451b44SJordan Rupprecht        process.Continue()
4399451b44SJordan Rupprecht
4499451b44SJordan Rupprecht        # resume the process and immediately try to set another breakpoint. When using the remote
4599451b44SJordan Rupprecht        # stub, this will trigger a request to stop the process.  Make sure we
4699451b44SJordan Rupprecht        # do not lose this signal.
4799451b44SJordan Rupprecht        bkpt = target.BreakpointCreateByAddress(0x1234)
4899451b44SJordan Rupprecht        self.assertTrue(bkpt.IsValid())
4999451b44SJordan Rupprecht        self.assertEqual(bkpt.GetNumLocations(), 1)
5099451b44SJordan Rupprecht
5199451b44SJordan Rupprecht        event = lldb.SBEvent()
5299451b44SJordan Rupprecht        while self.dbg.GetListener().WaitForEvent(2, event):
5399451b44SJordan Rupprecht            if self.TraceOn():
5499451b44SJordan Rupprecht                print("Process changing state to:",
5599451b44SJordan Rupprecht                    self.dbg.StateAsCString(process.GetStateFromEvent(event)))
5699451b44SJordan Rupprecht            if process.GetStateFromEvent(event) == lldb.eStateExited:
5799451b44SJordan Rupprecht                break
5899451b44SJordan Rupprecht
5999451b44SJordan Rupprecht        # We should get only one continue packet as the client should not
6099451b44SJordan Rupprecht        # auto-continue after setting the breakpoint.
6199451b44SJordan Rupprecht        self.assertEqual(self.server.responder.continueCount, 1)
6299451b44SJordan Rupprecht        # And the process should end up in the stopped state.
63*47c4c6a7SDave Lee        self.assertState(process.GetState(), lldb.eStateStopped)
64