summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestRestartBug.py62
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py33
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py86
3 files changed, 93 insertions, 88 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestRestartBug.py b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestRestartBug.py
new file mode 100644
index 00000000000..142861a37df
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestRestartBug.py
@@ -0,0 +1,62 @@
+from __future__ import print_function
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+
+class TestRestartBug(GDBRemoteTestBase):
+
+ @expectedFailureAll(bugnumber="llvm.org/pr24530")
+ def test(self):
+ """
+ Test auto-continue behavior when a process is interrupted to deliver
+ an "asynchronous" packet. This simulates the situation when a process
+ stops on its own just as lldb client is about to interrupt it. The
+ client should not auto-continue in this case, unless the user has
+ explicitly requested that we ignore signals of this type.
+ """
+ class MyResponder(MockGDBServerResponder):
+ continueCount = 0
+
+ def setBreakpoint(self, packet):
+ return "OK"
+
+ def interrupt(self):
+ # Simulate process stopping due to a raise(SIGINT) just as lldb
+ # is about to interrupt it.
+ return "T02reason:signal"
+
+ def cont(self):
+ self.continueCount += 1
+ if self.continueCount == 1:
+ # No response, wait for the client to interrupt us.
+ return None
+ return "W00" # Exit
+
+ self.server.responder = MyResponder()
+ target = self.createTarget("a.yaml")
+ process = self.connect(target)
+ self.dbg.SetAsync(True)
+ process.Continue()
+
+ # resume the process and immediately try to set another breakpoint. When using the remote
+ # stub, this will trigger a request to stop the process. Make sure we
+ # do not lose this signal.
+ bkpt = target.BreakpointCreateByAddress(0x1234)
+ self.assertTrue(bkpt.IsValid())
+ self.assertEqual(bkpt.GetNumLocations(), 1)
+
+ event = lldb.SBEvent()
+ while self.dbg.GetListener().WaitForEvent(2, event):
+ if self.TraceOn():
+ print("Process changing state to:",
+ self.dbg.StateAsCString(process.GetStateFromEvent(event)))
+ if process.GetStateFromEvent(event) == lldb.eStateExited:
+ break
+
+ # We should get only one continue packet as the client should not
+ # auto-continue after setting the breakpoint.
+ self.assertEqual(self.server.responder.continueCount, 1)
+ # And the process should end up in the stopped state.
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py
index 5293a32e7d1..9e175010a20 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py
@@ -98,6 +98,10 @@ class MockGDBServerResponder:
to the given packet received from the client.
"""
self.packetLog.append(packet)
+ if packet is MockGDBServer.PACKET_INTERRUPT:
+ return self.interrupt()
+ if packet == "c":
+ return self.cont()
if packet == "g":
return self.readRegisters()
if packet[0] == "G":
@@ -133,8 +137,16 @@ class MockGDBServerResponder:
if data is not None:
return self._qXferResponse(data, has_more)
return ""
+ if packet[0] == "Z":
+ return self.setBreakpoint(packet)
return self.other(packet)
+ def interrupt(self):
+ raise self.UnexpectedPacketException()
+
+ def cont(self):
+ raise self.UnexpectedPacketException()
+
def readRegisters(self):
return "00000000" * self.registerCount
@@ -178,10 +190,21 @@ class MockGDBServerResponder:
def selectThread(self, op, thread_id):
return "OK"
+ def setBreakpoint(self, packet):
+ raise self.UnexpectedPacketException()
+
def other(self, packet):
# empty string means unsupported
return ""
+ """
+ Raised when we receive a packet for which there is no default action.
+ Override the responder class to implement behavior suitable for the test at
+ hand.
+ """
+ class UnexpectedPacketException(Exception):
+ pass
+
class MockGDBServer:
"""
@@ -288,6 +311,9 @@ class MockGDBServer:
if data[0] == '+':
self._receivedData = data[1:]
return self.PACKET_ACK
+ if ord(data[0]) == 3:
+ self._receivedData = data[1:]
+ return self.PACKET_INTERRUPT
if data[0] == '$':
i += 1
else:
@@ -343,10 +369,12 @@ class MockGDBServer:
# Delegate everything else to our responder
response = self.responder.respond(packet)
# Handle packet framing since we don't want to bother tests with it.
- framed = frame_packet(response)
- self._client.sendall(framed)
+ if response is not None:
+ framed = frame_packet(response)
+ self._client.sendall(framed)
PACKET_ACK = object()
+ PACKET_INTERRUPT = object()
class InvalidPacketException(Exception):
pass
@@ -410,6 +438,7 @@ class GDBRemoteTestBase(TestBase):
process = target.ConnectRemote(listener, url, "gdb-remote", error)
self.assertTrue(error.Success(), error.description)
self.assertTrue(process, PROCESS_IS_VALID)
+ return process
def assertPacketLogContains(self, packets):
"""
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py b/lldb/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
index e8a2c598e27..dfc54a639ea 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
@@ -188,89 +188,3 @@ class RaiseTestCase(TestBase):
# reset signal handling to default
self.set_handle(signal, default_pass, default_stop, default_notify)
-
- @skipIfTargetAndroid()
- def test_restart_bug(self):
- """Test that we catch a signal in the edge case where the process receives it while we are
- about to interrupt it"""
- self.build()
- exe = self.getBuildArtifact("a.out")
-
- # Create a target by the debugger.
- target = self.dbg.CreateTarget(exe)
- self.assertTrue(target, VALID_TARGET)
- bkpt = target.BreakpointCreateByName("main")
- self.assertTrue(bkpt.IsValid(), VALID_BREAKPOINT)
-
- # launch the inferior and don't wait for it to stop
- self.dbg.SetAsync(True)
- error = lldb.SBError()
- listener = lldb.SBListener("my listener")
- process = target.Launch(listener,
- ["SIGSTOP"], # argv
- None, # envp
- None, # stdin_path
- None, # stdout_path
- None, # stderr_path
- None, # working directory
- 0, # launch flags
- False, # Stop at entry
- error) # error
-
- self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
-
- event = lldb.SBEvent()
-
- # Give the child enough time to reach the breakpoint,
- # while clearing out all the pending events.
- # The last WaitForEvent call will time out after 2 seconds.
- while listener.WaitForEvent(2, event):
- if self.TraceOn():
- print(
- "Process changing state to:",
- self.dbg.StateAsCString(
- process.GetStateFromEvent(event)))
-
- # now the process should be stopped
- self.assertEqual(
- process.GetState(),
- lldb.eStateStopped,
- PROCESS_STOPPED)
- self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(
- process, bkpt)), 1, "A thread should be stopped at breakpoint")
-
- # Remove all breakpoints. This makes sure we don't have to single-step over them when we
- # resume the process below
- target.DeleteAllBreakpoints()
-
- # resume the process and immediately try to set another breakpoint. When using the remote
- # stub, this will trigger a request to stop the process just as it is about to stop
- # naturally due to a SIGSTOP signal it raises. Make sure we do not lose
- # this signal.
- process.Continue()
- self.assertTrue(target.BreakpointCreateByName(
- "handler").IsValid(), VALID_BREAKPOINT)
-
- # Clear the events again
- while listener.WaitForEvent(2, event):
- if self.TraceOn():
- print(
- "Process changing state to:",
- self.dbg.StateAsCString(
- process.GetStateFromEvent(event)))
-
- # The process should be stopped due to a signal
- self.assertEqual(process.GetState(), lldb.eStateStopped)
- thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
- self.assertTrue(
- thread.IsValid(),
- "Thread should be stopped due to a signal")
- self.assertTrue(
- thread.GetStopReasonDataCount() >= 1,
- "There was data in the event.")
- signo = process.GetUnixSignals().GetSignalNumberFromName("SIGSTOP")
- self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo,
- "The stop signal was %s" % signal)
-
- # We are done
- process.Kill()
OpenPOWER on IntegriCloud