aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
diff options
context:
space:
mode:
authorMichał Górny <mgorny@moritz.systems>2022-04-12 16:21:09 +0200
committerMichał Górny <mgorny@moritz.systems>2022-06-21 19:04:20 +0200
commitbc04d240850bab340341eaf3601c5ca996667319 (patch)
tree944278a6b1a29d3be9e2f3c7dd0f24397fe6c1b4 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
parenteb12ad9d7ff64398add1a9cc84e56cc20aed09f8 (diff)
downloadllvm-bc04d240850bab340341eaf3601c5ca996667319.zip
llvm-bc04d240850bab340341eaf3601c5ca996667319.tar.gz
llvm-bc04d240850bab340341eaf3601c5ca996667319.tar.bz2
[lldb] [llgs] Implement non-stop style stop notification packets
Implement the support for %Stop asynchronous notification packet format in LLGS. This does not implement full support for non-stop mode for threaded programs -- process plugins continue stopping all threads on every event. However, it will be used to implement asynchronous events in multiprocess debugging. The non-stop protocol is enabled using QNonStop packet. When it is enabled, the server uses notification protocol instead of regular stop replies. Since all threads are always stopped, notifications are always generated for all active threads and copied into stop notification queue. If the queue was empty, the initial asynchronous %Stop notification is sent to the client immediately. The client needs to (eventually) acknowledge the notification by sending the vStopped packet, in which case it is popped from the queue and the stop reason for the next thread is reported. This continues until notification queue is empty again, in which case an OK reply is sent. Asychronous notifications are also used for vAttach results and program exits. The `?` packet uses a hybrid approach -- it returns the first stop reason synchronously, and exposes the stop reasons for remaining threads via vStopped queue. The change includes a test case for a program generating a segfault on 3 threads. The server is expected to generate a stop notification for the segfaulting thread, along with the notifications for the other running threads (with "no stop reason"). This verifies that the stop reasons are correctly reported for all threads, and that notification queue works. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.llvm.org/D125575
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index d660a4d..e5461c1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -125,6 +125,29 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunication::SendNotificationPacketNoLock(
+ llvm::StringRef notify_type, std::deque<std::string> &queue,
+ llvm::StringRef payload) {
+ PacketResult ret = PacketResult::Success;
+
+ // If there are no notification in the queue, send the notification
+ // packet.
+ if (queue.empty()) {
+ StreamString packet(0, 4, eByteOrderBig);
+ packet.PutChar('%');
+ packet.Write(notify_type.data(), notify_type.size());
+ packet.PutChar(':');
+ packet.Write(payload.data(), payload.size());
+ packet.PutChar('#');
+ packet.PutHex8(CalculcateChecksum(payload));
+ ret = SendRawPacketNoLock(packet.GetString(), true);
+ }
+
+ queue.push_back(payload.str());
+ return ret;
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
bool skip_ack) {
if (IsConnected()) {