diff options
author | Michał Górny <mgorny@moritz.systems> | 2022-06-12 08:55:41 +0200 |
---|---|---|
committer | Michał Górny <mgorny@moritz.systems> | 2022-06-24 17:20:23 +0200 |
commit | c18784ba330ac0f57e6ec433cfa8317349c445ff (patch) | |
tree | a87eef89f35b84f75e114d4b4efec5b32c53a04a /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp | |
parent | e8fe7e930a45764cbb88d9c3fa91ef7dc1ebcc97 (diff) | |
download | llvm-c18784ba330ac0f57e6ec433cfa8317349c445ff.zip llvm-c18784ba330ac0f57e6ec433cfa8317349c445ff.tar.gz llvm-c18784ba330ac0f57e6ec433cfa8317349c445ff.tar.bz2 |
[lldb] [llgs] Implement the vKill packet
Implement the support for the vKill packet. This is the modern packet
used by the GDB Remote Serial Protocol to kill one of the debugged
processes. Unlike the `k` packet, it has well-defined semantics.
The `vKill` packet takes the PID of the process to kill, and always
replies with an `OK` reply (rather than the exit status, as LLGS does
for `k` packets at the moment). Additionally, unlike the `k` packet
it does not cause the connection to be terminated once the last process
is killed — the client needs to close it explicitly.
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.llvm.org/D127667
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 434fb50..1ff0b7f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -233,6 +233,10 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { }); RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vKill, + &GDBRemoteCommunicationServerLLGS::Handle_vKill); + + RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore, &GDBRemoteCommunicationServerLLGS::Handle_qSaveCore); @@ -482,6 +486,10 @@ GDBRemoteCommunicationServerLLGS::SendWResponse( LLDB_LOG(log, "pid = {0}, returning exit type {1}", process->GetID(), *wait_status); + // If the process was killed through vKill, return "OK". + if (m_vkilled_processes.find(process->GetID()) != m_vkilled_processes.end()) + return SendOKResponse(); + StreamGDBRemote response; response.Format("{0:g}", *wait_status); if (bool(m_extensions_supported & NativeProcessProtocol::Extension::multiprocess)) @@ -1049,9 +1057,13 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( lldb::pid_t pid = process->GetID(); m_mainloop.AddPendingCallback([this, pid](MainLoopBase &loop) { m_debugged_processes.erase(pid); + auto vkill_it = m_vkilled_processes.find(pid); + if (vkill_it != m_vkilled_processes.end()) + m_vkilled_processes.erase(vkill_it); + // Terminate the main loop only if vKill has not been used. // When running in non-stop mode, wait for the vStopped to clear // the notification queue. - if (m_debugged_processes.empty() && !m_non_stop) { + else if (m_debugged_processes.empty() && !m_non_stop) { // Close the pipe to the inferior terminal i/o if we launched it and set // one up. MaybeCloseInferiorTerminalConnection(); @@ -1443,6 +1455,30 @@ GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { } GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_vKill( + StringExtractorGDBRemote &packet) { + StopSTDIOForwarding(); + + packet.SetFilePos(6); // vKill; + uint32_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); + if (pid == LLDB_INVALID_PROCESS_ID) + return SendIllFormedResponse(packet, + "vKill failed to parse the process id"); + + auto it = m_debugged_processes.find(pid); + if (it == m_debugged_processes.end()) + return SendErrorResponse(42); + + Status error = it->second->Kill(); + if (error.Fail()) + return SendErrorResponse(error.ToError()); + + // OK response is sent when the process dies. + m_vkilled_processes.insert(pid); + return PacketResult::Success; +} + +GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR( StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen("QSetDisableASLR:")); |