mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.
Support using the extended thread-id syntax with Hg packet to select
a subprocess. This makes it possible to start providing support for
running some of the debugger packets against another subprocesses.
https://reviews.llvm.org/D100261
Files:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -90,6 +90,7 @@
const NativeProcessProtocol::Factory &m_process_factory;
lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID;
lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID;
+ lldb::pid_t m_current_pid = LLDB_INVALID_PROCESS_ID;
std::recursive_mutex m_debugged_process_mutex;
std::unique_ptr<NativeProcessProtocol> m_debugged_process_up;
std::unordered_map<lldb::pid_t, std::unique_ptr<NativeProcessProtocol>>
@@ -233,9 +234,17 @@
// Verify and get the process instance selected by the client.
// If run is true, the process selected by "Hc" packet will be returned,
- // otherwise the one selected by "Hg" will be used. Returns nullptr if there
- // is no process debugged.
- NativeProcessProtocol *GetCurrentProcess(bool run) const;
+ // otherwise the one selected by "Hg" will be used.
+ //
+ // If allow_subprocess is true, a subprocess instance may be returned.
+ // Otherwise, only the main process can be returned and the function will
+ // return nullptr if a subprocess is selected.
+ //
+ // Returns nullptr if there is no process debugged.
+ NativeProcessProtocol *GetCurrentProcess(bool run,
+ bool allow_subprocess = false) const;
+
+ void SetCurrentProcessID(lldb::pid_t pid, lldb::tid_t tid);
private:
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml();
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1624,6 +1624,9 @@
m_current_tid = tid;
if (m_debugged_process_up)
m_debugged_process_up->SetCurrentThreadID(m_current_tid);
+
+ // Reset subprocess support
+ m_current_pid = LLDB_INVALID_PROCESS_ID;
}
void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
@@ -2081,12 +2084,32 @@
}
// Parse out the thread number.
- llvm::Expected<lldb::tid_t> tid_ret =
- ReadTid(packet, /*run=*/h_variant == 'c', /*allow_all=*/true);
- if (!tid_ret)
- return SendErrorResponse(tid_ret.takeError());
+ auto *process = GetCurrentProcess(h_variant == 'c', true);
+ auto pid_tid =
+ packet.GetPidTid(process ? process->GetID() : LLDB_INVALID_PROCESS_ID);
+ if (!pid_tid)
+ return SendErrorResponse(llvm::make_error<StringError>(
+ inconvertibleErrorCode(), "Malformed thread-id"));
+
+ lldb::pid_t pid = pid_tid->first;
+ lldb::tid_t tid = pid_tid->second;
+
+ if (pid == StringExtractorGDBRemote::AllProcesses)
+ return SendUnimplementedResponse("Selecting all processes not supported");
+ if (pid != m_debugged_process_up->GetID()) {
+ // Is it a subprocess?
+ if (m_additional_processes.find(pid) == m_additional_processes.end())
+ return SendErrorResponse(llvm::make_error<StringError>(
+ inconvertibleErrorCode(),
+ llvm::formatv("PID {0} not debugged", pid)));
+ if (h_variant != 'g')
+ return SendUnimplementedResponse(
+ "Hc packet for subprocess not supported");
+
+ SetCurrentProcessID(pid, tid);
+ return SendOKResponse();
+ }
- lldb::tid_t tid = tid_ret.get();
// Ensure we have the given thread when not specifying -1 (all threads) or 0
// (any thread).
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
@@ -2622,7 +2645,7 @@
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
- auto *process = GetCurrentProcess(false);
+ auto *process = GetCurrentProcess(false, true);
if (!process) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
LLDB_LOG(log, "failed, no process available");
@@ -3622,12 +3645,33 @@
"Enabling protocol extensions failed: {0}");
}
-NativeProcessProtocol *
-GDBRemoteCommunicationServerLLGS::GetCurrentProcess(bool run) const {
+NativeProcessProtocol *GDBRemoteCommunicationServerLLGS::GetCurrentProcess(
+ bool run, bool allow_subprocess) const {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
return nullptr;
+ // Check if another process was selected via Hg.
+ if (!run && m_current_pid != LLDB_INVALID_PROCESS_ID &&
+ m_current_pid != m_debugged_process_up->GetID()) {
+ if (!allow_subprocess)
+ return nullptr;
+
+ auto it = m_additional_processes.find(m_current_pid);
+ if (it == m_additional_processes.end())
+ return nullptr;
+ return it->second.get();
+ }
+
return m_debugged_process_up.get();
}
+
+void GDBRemoteCommunicationServerLLGS::SetCurrentProcessID(lldb::pid_t pid,
+ lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ LLDB_LOG(log, "setting current subprocess to {0}, thread id {1}", pid, tid);
+
+ m_current_pid = pid;
+ m_current_tid = tid;
+}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits