aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
diff options
context:
space:
mode:
authorMichał Górny <mgorny@moritz.systems>2022-06-29 21:48:10 +0200
committerMichał Górny <mgorny@moritz.systems>2022-07-15 17:20:39 +0200
commit1903f358bcc74fd96c65f0d1deba577c63238c86 (patch)
tree6e05de7b758bf8db603c9c180ccedf1b28b189e9 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
parentb9f5b02fd071d494f828c3c9c2b25c671a457928 (diff)
downloadllvm-1903f358bcc74fd96c65f0d1deba577c63238c86.zip
llvm-1903f358bcc74fd96c65f0d1deba577c63238c86.tar.gz
llvm-1903f358bcc74fd96c65f0d1deba577c63238c86.tar.bz2
[lldb] [llgs] Send process output asynchronously in non-stop mode
Introduce a new %Stdio notification category and use it to send process output asynchronously when running in non-stop mode. This is an LLDB extension since GDB does not use the 'O' packet for process output, just for replies to 'qRcmd' packets. Using the async notification mechanism implies that only the first output packet is sent immediately to the client. The client needs to request subsequent notifications (if any) using the new vStdio packet (that works pretty much like vStopped for the Stop notification queue). The packet handler in lldb-server tests is updated to handle the async stdio packets in addition to the regular O packets. However, due to the implications noted above, it can only handle the first output packet sent by the server. Subsequent packets need to be explicitly requested via vStdio. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.llvm.org/D128849
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 8edb49f..49f37ba 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -246,6 +246,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
StringExtractorGDBRemote::eServerPacketType_QNonStop,
&GDBRemoteCommunicationServerLLGS::Handle_QNonStop);
RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vStdio,
+ &GDBRemoteCommunicationServerLLGS::Handle_vStdio);
+ RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vStopped,
&GDBRemoteCommunicationServerLLGS::Handle_vStopped);
RegisterMemberFunctionHandler(
@@ -1192,6 +1195,9 @@ GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer,
response.PutChar('O');
response.PutBytesAsRawHex8(buffer, len);
+ if (m_non_stop)
+ return SendNotificationPacketNoLock("Stdio", m_stdio_notification_queue,
+ response.GetString());
return SendPacketNoLock(response.GetString());
}
@@ -3907,26 +3913,38 @@ GDBRemoteCommunicationServerLLGS::Handle_QNonStop(
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vStopped(
- StringExtractorGDBRemote &packet) {
+GDBRemoteCommunicationServerLLGS::HandleNotificationAck(
+ std::deque<std::string> &queue) {
// Per the protocol, the first message put into the queue is sent
- // immediately. However, it remains the queue until the client ACKs
- // it via vStopped -- then we pop it and send the next message.
- // The process repeats until the last message in the queue is ACK-ed,
- // in which case the vStopped packet sends an OK response.
-
- if (m_stop_notification_queue.empty())
+ // immediately. However, it remains the queue until the client ACKs it --
+ // then we pop it and send the next message. The process repeats until
+ // the last message in the queue is ACK-ed, in which case the packet sends
+ // an OK response.
+ if (queue.empty())
return SendErrorResponse(Status("No pending notification to ack"));
- m_stop_notification_queue.pop_front();
- if (!m_stop_notification_queue.empty())
- return SendPacketNoLock(m_stop_notification_queue.front());
+ queue.pop_front();
+ if (!queue.empty())
+ return SendPacketNoLock(queue.front());
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vStdio(
+ StringExtractorGDBRemote &packet) {
+ return HandleNotificationAck(m_stdio_notification_queue);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vStopped(
+ StringExtractorGDBRemote &packet) {
+ PacketResult ret = HandleNotificationAck(m_stop_notification_queue);
// If this was the last notification and all the processes exited,
// terminate the server.
- if (m_debugged_processes.empty()) {
+ if (m_stop_notification_queue.empty() && m_debugged_processes.empty()) {
m_exit_now = true;
m_mainloop.RequestTermination();
}
- return SendOKResponse();
+ return ret;
}
GDBRemoteCommunication::PacketResult