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