forked from OSchip/llvm-project
[lldb] [gdb-remote client] Support switching PID along with TID
Extend the SetCurrentThread() method to support specifying an alternate PID to switch to. This makes it possible to issue requests to forked processes. Differential Revision: https://reviews.llvm.org/D100262
This commit is contained in:
parent
0111da2ef8
commit
aa319f544a
|
@ -713,7 +713,8 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
|
|||
PacketResult::Success) {
|
||||
if (response.GetChar() == 'Q') {
|
||||
if (response.GetChar() == 'C') {
|
||||
m_curr_pid = response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
|
||||
m_curr_pid_run = m_curr_pid =
|
||||
response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
|
||||
if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
|
||||
m_curr_pid_is_valid = eLazyBoolYes;
|
||||
return m_curr_pid;
|
||||
|
@ -729,10 +730,10 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
|
|||
auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
|
||||
if (!ids.empty() && !sequence_mutex_unavailable) {
|
||||
// If server returned an explicit PID, use that.
|
||||
m_curr_pid = ids.front().first;
|
||||
m_curr_pid_run = m_curr_pid = ids.front().first;
|
||||
// Otherwise, use the TID of the first thread (Linux hack).
|
||||
if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
|
||||
m_curr_pid = ids.front().second;
|
||||
m_curr_pid_run = m_curr_pid = ids.front().second;
|
||||
m_curr_pid_is_valid = eLazyBoolYes;
|
||||
return m_curr_pid;
|
||||
}
|
||||
|
@ -1123,7 +1124,7 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
|
|||
|
||||
// if we get pid as well, update m_curr_pid
|
||||
if (pid != 0) {
|
||||
m_curr_pid = pid;
|
||||
m_curr_pid_run = m_curr_pid = pid;
|
||||
m_curr_pid_is_valid = eLazyBoolYes;
|
||||
}
|
||||
tid = pid_tid->second;
|
||||
|
@ -2137,7 +2138,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
|
|||
m_qProcessInfo_is_valid = eLazyBoolYes;
|
||||
if (pid != LLDB_INVALID_PROCESS_ID) {
|
||||
m_curr_pid_is_valid = eLazyBoolYes;
|
||||
m_curr_pid = pid;
|
||||
m_curr_pid_run = m_curr_pid = pid;
|
||||
}
|
||||
|
||||
// Set the ArchSpec from the triple if we have it.
|
||||
|
@ -2639,21 +2640,30 @@ bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
|
|||
return false;
|
||||
}
|
||||
|
||||
llvm::Optional<uint64_t>
|
||||
llvm::Optional<PidTid>
|
||||
GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
|
||||
uint64_t pid,
|
||||
char op) {
|
||||
lldb_private::StreamString packet;
|
||||
packet.PutChar('H');
|
||||
packet.PutChar(op);
|
||||
|
||||
if (pid != LLDB_INVALID_PROCESS_ID) {
|
||||
packet.PutChar('p');
|
||||
packet.PutHex64(pid);
|
||||
packet.PutChar('.');
|
||||
}
|
||||
|
||||
if (tid == UINT64_MAX)
|
||||
packet.PutCString("-1");
|
||||
else
|
||||
packet.PutHex64(tid);
|
||||
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
|
||||
PacketResult::Success) {
|
||||
if (response.IsOKResponse())
|
||||
return tid;
|
||||
return {{pid, tid}};
|
||||
|
||||
/*
|
||||
* Connected bare-iron target (like YAMON gdb-stub) may not have support for
|
||||
|
@ -2663,28 +2673,38 @@ GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
|
|||
* give us pid and/or tid. Assume pid=tid=1 in such cases.
|
||||
*/
|
||||
if (response.IsUnsupportedResponse() && IsConnected())
|
||||
return 1;
|
||||
return {{1, 1}};
|
||||
}
|
||||
return llvm::None;
|
||||
}
|
||||
|
||||
bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
|
||||
if (m_curr_tid == tid)
|
||||
bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
|
||||
uint64_t pid) {
|
||||
if (m_curr_tid == tid &&
|
||||
(m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
|
||||
return true;
|
||||
|
||||
llvm::Optional<uint64_t> ret = SendSetCurrentThreadPacket(tid, 'g');
|
||||
if (ret.hasValue())
|
||||
m_curr_tid = ret.getValue();
|
||||
llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
|
||||
if (ret.hasValue()) {
|
||||
if (ret->pid != LLDB_INVALID_PROCESS_ID)
|
||||
m_curr_pid = ret->pid;
|
||||
m_curr_tid = ret->tid;
|
||||
}
|
||||
return ret.hasValue();
|
||||
}
|
||||
|
||||
bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
|
||||
if (m_curr_tid_run == tid)
|
||||
bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
|
||||
uint64_t pid) {
|
||||
if (m_curr_tid_run == tid &&
|
||||
(m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
|
||||
return true;
|
||||
|
||||
llvm::Optional<uint64_t> ret = SendSetCurrentThreadPacket(tid, 'c');
|
||||
if (ret.hasValue())
|
||||
m_curr_tid_run = ret.getValue();
|
||||
llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
|
||||
if (ret.hasValue()) {
|
||||
if (ret->pid != LLDB_INVALID_PROCESS_ID)
|
||||
m_curr_pid_run = ret->pid;
|
||||
m_curr_tid_run = ret->tid;
|
||||
}
|
||||
return ret.hasValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,12 @@ inline bool operator==(const QOffsets &a, const QOffsets &b) {
|
|||
}
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets);
|
||||
|
||||
// A trivial struct used to return a pair of PID and TID.
|
||||
struct PidTid {
|
||||
uint64_t pid;
|
||||
uint64_t tid;
|
||||
};
|
||||
|
||||
class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
|
||||
public:
|
||||
GDBRemoteCommunicationClient();
|
||||
|
@ -336,11 +342,14 @@ public:
|
|||
// and response times.
|
||||
bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
|
||||
|
||||
llvm::Optional<uint64_t> SendSetCurrentThreadPacket(uint64_t tid, char op);
|
||||
llvm::Optional<PidTid>
|
||||
SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op);
|
||||
|
||||
bool SetCurrentThread(uint64_t tid);
|
||||
bool SetCurrentThread(uint64_t tid,
|
||||
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
|
||||
|
||||
bool SetCurrentThreadForRun(uint64_t tid);
|
||||
bool SetCurrentThreadForRun(uint64_t tid,
|
||||
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
|
||||
|
||||
bool GetQXferAuxvReadSupported();
|
||||
|
||||
|
@ -576,13 +585,14 @@ protected:
|
|||
m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
|
||||
m_supports_jModulesInfo : 1;
|
||||
|
||||
/// Current gdb remote protocol process identifier for all other operations
|
||||
lldb::pid_t m_curr_pid = LLDB_INVALID_PROCESS_ID;
|
||||
lldb::tid_t m_curr_tid =
|
||||
LLDB_INVALID_THREAD_ID; // Current gdb remote protocol thread index for
|
||||
// all other operations
|
||||
lldb::tid_t m_curr_tid_run =
|
||||
LLDB_INVALID_THREAD_ID; // Current gdb remote protocol thread index for
|
||||
// continue, step, etc
|
||||
/// Current gdb remote protocol process identifier for continue, step, etc
|
||||
lldb::pid_t m_curr_pid_run = LLDB_INVALID_PROCESS_ID;
|
||||
/// Current gdb remote protocol thread identifier for all other operations
|
||||
lldb::tid_t m_curr_tid = LLDB_INVALID_THREAD_ID;
|
||||
/// Current gdb remote protocol thread identifier for continue, step, etc
|
||||
lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
|
||||
|
||||
uint32_t m_num_supported_hardware_watchpoints = 0;
|
||||
uint32_t m_addressing_bits = 0;
|
||||
|
|
Loading…
Reference in New Issue