Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -334,11 +334,14 @@ // and response times. bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size); - llvm::Optional SendSetCurrentThreadPacket(uint64_t tid, char type); + llvm::Optional> + SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char type); - 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(); @@ -569,6 +572,7 @@ m_supports_jModulesInfo : 1; lldb::pid_t m_curr_pid; + lldb::pid_t m_curr_pid_run; lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all // other operations lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -98,7 +98,9 @@ m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true), m_qSymbol_requests_done(false), m_supports_qModuleInfo(true), m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true), - m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID), + m_curr_pid(LLDB_INVALID_PROCESS_ID), + m_curr_pid_run(LLDB_INVALID_PROCESS_ID), + m_curr_tid(LLDB_INVALID_THREAD_ID), m_curr_tid_run(LLDB_INVALID_THREAD_ID), m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(), @@ -696,7 +698,8 @@ 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; @@ -712,10 +715,10 @@ 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; } @@ -1106,7 +1109,7 @@ // 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; @@ -2095,7 +2098,7 @@ 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. @@ -2597,21 +2600,30 @@ return false; } -llvm::Optional +llvm::Optional> GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid, + uint64_t pid, char type) { lldb_private::StreamString packet; packet.PutChar('H'); packet.PutChar(type); + + 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 @@ -2621,28 +2633,40 @@ * 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 ret = SendSetCurrentThreadPacket(tid, 'g'); - if (ret.hasValue()) - m_curr_tid = ret.getValue(); + llvm::Optional> ret = + SendSetCurrentThreadPacket(tid, pid, 'g'); + if (ret.hasValue()) { + if (ret->first != LLDB_INVALID_PROCESS_ID) + m_curr_pid = ret->first; + m_curr_tid = ret->second; + } 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 ret = SendSetCurrentThreadPacket(tid, 'c'); - if (ret.hasValue()) - m_curr_tid_run = ret.getValue(); + llvm::Optional> ret = + SendSetCurrentThreadPacket(tid, pid, 'c'); + if (ret.hasValue()) { + if (ret->first != LLDB_INVALID_PROCESS_ID) + m_curr_pid_run = ret->first; + m_curr_tid_run = ret->second; + } return ret.hasValue(); }