aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp38
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h5
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp27
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp5
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h1
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp701
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h47
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp21
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp12
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp311
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h16
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h2
15 files changed, 693 insertions, 499 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index 8364ffeef46f..e3a3cfc4f23e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -347,7 +347,7 @@ GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm,
}
void GDBRemoteClientBase::Lock::SyncWithContinueThread() {
- Log *log = GetLog(GDBRLog::Process);
+ Log *log = GetLog(GDBRLog::Process|GDBRLog::Packets);
std::unique_lock<std::mutex> lock(m_comm.m_mutex);
if (m_comm.m_is_running && m_interrupt_timeout == std::chrono::seconds(0))
return; // We were asked to avoid interrupting the sender. Lock is not
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 38d9e400978d..e5461c1899ec 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -125,6 +125,29 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunication::SendNotificationPacketNoLock(
+ llvm::StringRef notify_type, std::deque<std::string> &queue,
+ llvm::StringRef payload) {
+ PacketResult ret = PacketResult::Success;
+
+ // If there are no notification in the queue, send the notification
+ // packet.
+ if (queue.empty()) {
+ StreamString packet(0, 4, eByteOrderBig);
+ packet.PutChar('%');
+ packet.Write(notify_type.data(), notify_type.size());
+ packet.PutChar(':');
+ packet.Write(payload.data(), payload.size());
+ packet.PutChar('#');
+ packet.PutHex8(CalculcateChecksum(payload));
+ ret = SendRawPacketNoLock(packet.GetString(), true);
+ }
+
+ queue.push_back(payload.str());
+ return ret;
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
bool skip_ack) {
if (IsConnected()) {
@@ -843,7 +866,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname,
m_listen_url = listen_url;
SetConnection(std::make_unique<ConnectionFileDescriptor>());
llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread(
- listen_url, GDBRemoteCommunication::ListenThread, this);
+ listen_url, [this] { return GDBRemoteCommunication::ListenThread(); });
if (!listen_thread)
return Status(listen_thread.takeError());
m_listen_thread = *listen_thread;
@@ -857,23 +880,22 @@ bool GDBRemoteCommunication::JoinListenThread() {
return true;
}
-lldb::thread_result_t
-GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
- GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+lldb::thread_result_t GDBRemoteCommunication::ListenThread() {
Status error;
ConnectionFileDescriptor *connection =
- (ConnectionFileDescriptor *)comm->GetConnection();
+ (ConnectionFileDescriptor *)GetConnection();
if (connection) {
// Do the listen on another thread so we can continue on...
if (connection->Connect(
- comm->m_listen_url.c_str(), [comm](llvm::StringRef port_str) {
+ m_listen_url.c_str(),
+ [this](llvm::StringRef port_str) {
uint16_t port = 0;
llvm::to_integer(port_str, port, 10);
- comm->m_port_promise.set_value(port);
+ m_port_promise.set_value(port);
},
&error) != eConnectionStatusSuccess)
- comm->SetConnection(nullptr);
+ SetConnection(nullptr);
}
return {};
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index afc7e740d4c9..35e86c202b5b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -183,6 +183,9 @@ protected:
CompressionType m_compression_type;
PacketResult SendPacketNoLock(llvm::StringRef payload);
+ PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type,
+ std::deque<std::string>& queue,
+ llvm::StringRef payload);
PacketResult SendRawPacketNoLock(llvm::StringRef payload,
bool skip_ack = false);
@@ -218,7 +221,7 @@ protected:
bool JoinListenThread();
- static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
+ lldb::thread_result_t ListenThread();
private:
// Promise used to grab the port number from listening thread
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 91b9151328a8..700e6ebdf84c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -24,6 +24,7 @@
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
@@ -642,7 +643,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,
}
size_t expected_bytes = response.GetBytesLeft() / 2;
- DataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
+ WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
// Check both because in some situations chars are consumed even
// if the decoding fails.
@@ -2227,8 +2228,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
break;
case llvm::Triple::GOFF:
+ case llvm::Triple::SPIRV:
case llvm::Triple::Wasm:
case llvm::Triple::XCOFF:
+ case llvm::Triple::DXContainer:
LLDB_LOGF(log, "error: not supported target architecture");
return false;
case llvm::Triple::UnknownObjectFormat:
@@ -2245,9 +2248,6 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
- m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
- m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
- m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
}
return true;
}
@@ -2697,8 +2697,8 @@ GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
packet.Printf("%" PRIx64, tid);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response)
- == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
+ PacketResult::Success) {
if (response.IsOKResponse())
return {{pid, tid}};
@@ -2722,7 +2722,7 @@ bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
return true;
llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
- if (ret.hasValue()) {
+ if (ret) {
if (ret->pid != LLDB_INVALID_PROCESS_ID)
m_curr_pid = ret->pid;
m_curr_tid = ret->tid;
@@ -2737,7 +2737,7 @@ bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
return true;
llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
- if (ret.hasValue()) {
+ if (ret) {
if (ret->pid != LLDB_INVALID_PROCESS_ID)
m_curr_pid_run = ret->pid;
m_curr_tid_run = ret->tid;
@@ -2778,7 +2778,7 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo(
uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
std::chrono::seconds timeout) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
__FUNCTION__, insert ? "add" : "remove", addr);
@@ -2865,7 +2865,7 @@ GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
if (!pid_tid)
break;
- ids.push_back(pid_tid.getValue());
+ ids.push_back(*pid_tid);
ch = response.GetChar(); // Skip the command separator
} while (ch == ','); // Make sure we got a comma separator
}
@@ -3443,7 +3443,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
!response.IsNormalResponse())
return nullptr;
- DataBufferSP buffer_sp(
+ WritableDataBufferSP buffer_sp(
new DataBufferHeap(response.GetStringRef().size() / 2, 0));
response.GetHexBytes(buffer_sp->GetData(), '\xcc');
return buffer_sp;
@@ -3458,7 +3458,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
!response.IsNormalResponse())
return nullptr;
- DataBufferSP buffer_sp(
+ WritableDataBufferSP buffer_sp(
new DataBufferHeap(response.GetStringRef().size() / 2, 0));
response.GetHexBytes(buffer_sp->GetData(), '\xcc');
return buffer_sp;
@@ -3701,9 +3701,6 @@ GDBRemoteCommunicationClient::SendTraceGetBinaryData(
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsErrorResponse())
return response.GetStatus().ToError();
- if (response.IsUnsupportedResponse())
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "jLLDBTraceGetBinaryData is unsupported");
std::string data;
response.GetEscapedBinaryData(data);
return std::vector<uint8_t>(data.begin(), data.end());
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index f371649842e8..2a58f2028386 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -30,6 +30,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/GDBRemote.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
@@ -426,7 +427,7 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qUserName(
StringExtractorGDBRemote &packet) {
#if LLDB_ENABLE_POSIX
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
// Packet format: "qUserName:%i" where %i is the uid
@@ -1020,7 +1021,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
// encoded argument value list, but we will stay true to the documented
// version of the 'A' packet here...
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
int actual_arg_index = 0;
packet.SetFilePos(1); // Skip the 'A'
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index 029972348ef0..f696cb5c61c6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -15,7 +15,6 @@
#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationServer.h"
-#include "GDBRemoteCommunicationServerCommon.h"
class StringExtractorGDBRemote;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 123a8198a89b..63174ef55219 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -35,6 +35,7 @@
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/State.h"
@@ -106,6 +107,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
&GDBRemoteCommunicationServerLLGS::Handle_P);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
&GDBRemoteCommunicationServerLLGS::Handle_qC);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_T,
+ &GDBRemoteCommunicationServerLLGS::Handle_T);
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
&GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
@@ -232,8 +235,22 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
});
RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vKill,
+ &GDBRemoteCommunicationServerLLGS::Handle_vKill);
+
+ RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore,
&GDBRemoteCommunicationServerLLGS::Handle_qSaveCore);
+
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QNonStop,
+ &GDBRemoteCommunicationServerLLGS::Handle_QNonStop);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vStopped,
+ &GDBRemoteCommunicationServerLLGS::Handle_vStopped);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vCtrlC,
+ &GDBRemoteCommunicationServerLLGS::Handle_vCtrlC);
}
void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) {
@@ -241,7 +258,7 @@ void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &in
}
Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (!m_process_launch_info.GetArguments().GetArgumentCount())
return Status("%s: no process command line specified to launch",
@@ -323,7 +340,7 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
}
Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
__FUNCTION__, pid);
@@ -370,7 +387,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
llvm::StringRef process_name, bool include_existing) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1);
@@ -440,7 +457,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (log) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s called with "
@@ -454,7 +471,7 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::SendWResponse(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// send W notification
auto wait_status = process->GetExitStatus();
@@ -471,8 +488,17 @@ 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))
+ response.Format(";process:{0:x-}", process->GetID());
+ if (m_non_stop)
+ return SendNotificationPacketNoLock("Stop", m_stop_notification_queue,
+ response.GetString());
return SendPacketNoLock(response.GetString());
}
@@ -608,7 +634,7 @@ static void WriteRegisterValueInHexFixedWidth(
static llvm::Optional<json::Object>
GetRegistersAsJSON(NativeThreadProtocol &thread) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
@@ -693,26 +719,21 @@ static const char *GetStopReasonString(StopReason stop_reason) {
static llvm::Expected<json::Array>
GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
json::Array threads_array;
// Ensure we can get info on the given thread.
- uint32_t thread_idx = 0;
- for (NativeThreadProtocol *thread;
- (thread = process.GetThreadAtIndex(thread_idx)) != nullptr;
- ++thread_idx) {
-
- lldb::tid_t tid = thread->GetID();
-
+ for (NativeThreadProtocol &thread : process.Threads()) {
+ lldb::tid_t tid = thread.GetID();
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread->GetStopReason(tid_stop_info, description))
+ if (!thread.GetStopReason(tid_stop_info, description))
return llvm::make_error<llvm::StringError>(
"failed to get stop reason", llvm::inconvertibleErrorCode());
- const int signum = tid_stop_info.details.signal.signo;
+ const int signum = tid_stop_info.signo;
if (log) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
@@ -725,7 +746,7 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
json::Object thread_obj;
if (!abridged) {
- if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(*thread))
+ if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(thread))
thread_obj.try_emplace("registers", std::move(*registers));
}
@@ -734,7 +755,7 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
if (signum != 0)
thread_obj.try_emplace("signal", signum);
- const std::string thread_name = thread->GetName();
+ const std::string thread_name = thread.GetName();
if (!thread_name.empty())
thread_obj.try_emplace("name", thread_name);
@@ -763,29 +784,22 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
return threads_array;
}
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
- lldb::tid_t tid) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
- // Ensure we have a debugged process.
- if (!m_current_process ||
- (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse(50);
+StreamString
+GDBRemoteCommunicationServerLLGS::PrepareStopReplyPacketForThread(
+ NativeThreadProtocol &thread) {
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
- LLDB_LOG(log, "preparing packet for pid {0} tid {1}",
- m_current_process->GetID(), tid);
+ NativeProcessProtocol &process = thread.GetProcess();
- // Ensure we can get info on the given thread.
- NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid);
- if (!thread)
- return SendErrorResponse(51);
+ LLDB_LOG(log, "preparing packet for pid {0} tid {1}", process.GetID(),
+ thread.GetID());
// Grab the reason this thread stopped.
+ StreamString response;
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread->GetStopReason(tid_stop_info, description))
- return SendErrorResponse(52);
+ if (!thread.GetStopReason(tid_stop_info, description))
+ return response;
// FIXME implement register handling for exec'd inferiors.
// if (tid_stop_info.reason == eStopReasonExec) {
@@ -793,24 +807,25 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
// InitializeRegisters(force);
// }
- StreamString response;
// Output the T packet with the thread
response.PutChar('T');
- int signum = tid_stop_info.details.signal.signo;
+ int signum = tid_stop_info.signo;
LLDB_LOG(
log,
"pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}",
- m_current_process->GetID(), tid, signum, int(tid_stop_info.reason),
+ process.GetID(), thread.GetID(), signum, int(tid_stop_info.reason),
tid_stop_info.details.exception.type);
// Print the signal number.
response.PutHex8(signum & 0xff);
- // Include the tid.
- response.Printf("thread:%" PRIx64 ";", tid);
+ // Include the (pid and) tid.
+ response.PutCString("thread:");
+ AppendThreadIDToResponse(response, process.GetID(), thread.GetID());
+ response.PutChar(';');
// Include the thread name if there is one.
- const std::string thread_name = thread->GetName();
+ const std::string thread_name = thread.GetName();
if (!thread_name.empty()) {
size_t thread_name_len = thread_name.length();
@@ -836,14 +851,12 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
if (m_list_threads_in_stop_reply) {
response.PutCString("threads:");
- uint32_t thread_index = 0;
- NativeThreadProtocol *listed_thread;
- for (listed_thread = m_current_process->GetThreadAtIndex(thread_index);
- listed_thread; ++thread_index,
- listed_thread = m_current_process->GetThreadAtIndex(thread_index)) {
- if (thread_index > 0)
+ uint32_t thread_num = 0;
+ for (NativeThreadProtocol &listed_thread : process.Threads()) {
+ if (thread_num > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, listed_thread->GetID());
+ response.Printf("%" PRIx64, listed_thread.GetID());
+ ++thread_num;
}
response.PutChar(';');
@@ -852,7 +865,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
// is hex ascii JSON that contains the thread IDs thread stop info only for
// threads that have stop reasons. Only send this if we have more than one
// thread otherwise this packet has all the info it needs.
- if (thread_index > 1) {
+ if (thread_num > 1) {
const bool threads_with_valid_stop_info_only = true;
llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo(
*m_current_process, threads_with_valid_stop_info_only);
@@ -865,16 +878,14 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
} else {
LLDB_LOG_ERROR(log, threads_info.takeError(),
"failed to prepare a jstopinfo field for pid {1}: {0}",
- m_current_process->GetID());
+ process.GetID());
}
}
- uint32_t i = 0;
response.PutCString("thread-pcs");
char delimiter = ':';
- for (NativeThreadProtocol *thread;
- (thread = m_current_process->GetThreadAtIndex(i)) != nullptr; ++i) {
- NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
+ for (NativeThreadProtocol &thread : process.Threads()) {
+ NativeRegisterContext &reg_ctx = thread.GetRegisterContext();
uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
@@ -905,7 +916,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
//
// Grab the register context.
- NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
+ NativeRegisterContext &reg_ctx = thread.GetRegisterContext();
const auto expedited_regs =
reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full);
@@ -922,8 +933,9 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
&reg_value, lldb::eByteOrderBig);
response.PutChar(';');
} else {
- LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
reg_num, error.AsCString());
@@ -972,17 +984,53 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
tid_stop_info.details.fork.child_tid);
}
+ return response;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
+ NativeProcessProtocol &process, lldb::tid_t tid, bool force_synchronous) {
+ // Ensure we can get info on the given thread.
+ NativeThreadProtocol *thread = process.GetThreadByID(tid);
+ if (!thread)
+ return SendErrorResponse(51);
+
+ StreamString response = PrepareStopReplyPacketForThread(*thread);
+ if (response.Empty())
+ return SendErrorResponse(42);
+
+ if (m_non_stop && !force_synchronous) {
+ PacketResult ret = SendNotificationPacketNoLock(
+ "Stop", m_stop_notification_queue, response.GetString());
+ // Queue notification events for the remaining threads.
+ EnqueueStopReplyPackets(tid);
+ return ret;
+ }
+
return SendPacketNoLock(response.GetString());
}
+void GDBRemoteCommunicationServerLLGS::EnqueueStopReplyPackets(
+ lldb::tid_t thread_to_skip) {
+ if (!m_non_stop)
+ return;
+
+ for (NativeThreadProtocol &listed_thread : m_current_process->Threads()) {
+ if (listed_thread.GetID() != thread_to_skip)
+ m_stop_notification_queue.push_back(
+ PrepareStopReplyPacketForThread(listed_thread).GetString().str());
+ }
+}
+
void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- PacketResult result = SendStopReasonForState(StateType::eStateExited);
+ PacketResult result = SendStopReasonForState(
+ *process, StateType::eStateExited, /*force_synchronous=*/false);
if (result != PacketResult::Success) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s failed to send stop "
@@ -990,20 +1038,37 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
__FUNCTION__, process->GetID());
}
- // Close the pipe to the inferior terminal i/o if we launched it and set one
- // up.
- MaybeCloseInferiorTerminalConnection();
+ if (m_current_process == process)
+ m_current_process = nullptr;
+ if (m_continue_process == process)
+ m_continue_process = nullptr;
+
+ 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.
+ 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();
- // We are ready to exit the debug monitor.
- m_exit_now = true;
- m_mainloop.RequestTermination();
+ // We are ready to exit the debug monitor.
+ m_exit_now = true;
+ loop.RequestTermination();
+ }
+ });
}
void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Send the stop reason unless this is the stop after the launch or attach.
@@ -1014,7 +1079,8 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
break;
default:
// In all other cases, send the stop reason.
- PacketResult result = SendStopReasonForState(StateType::eStateStopped);
+ PacketResult result = SendStopReasonForState(
+ *process, StateType::eStateStopped, /*force_synchronous=*/false);
if (result != PacketResult::Success) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s failed to send stop "
@@ -1028,7 +1094,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
NativeProcessProtocol *process, lldb::StateType state) {
assert(process && "process cannot be NULL");
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (log) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s called with "
@@ -1038,7 +1104,6 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
switch (state) {
case StateType::eStateRunning:
- StartSTDIOForwarding();
break;
case StateType::eStateStopped:
@@ -1163,7 +1228,7 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
return;
Status error;
- lldbassert(!m_stdio_handle_up);
+ assert(!m_stdio_handle_up);
m_stdio_handle_up = m_mainloop.RegisterReadObject(
m_stdio_communication.GetConnection()->GetReadObject(),
[this](MainLoopBase &) { SendProcessOutput(); }, error);
@@ -1171,11 +1236,8 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
if (!m_stdio_handle_up) {
// Not much we can do about the failure. Log it and continue without
// forwarding.
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
- "forwarding: %s",
- __FUNCTION__, error.AsCString());
+ if (Log *log = GetLog(LLDBLog::Process))
+ LLDB_LOG(log, "Failed to set up stdio forwarding: {0}", error);
}
}
@@ -1198,7 +1260,7 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
case eConnectionStatusEndOfFile:
case eConnectionStatusError:
case eConnectionStatusNoConnection:
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+ if (Log *log = GetLog(LLDBLog::Process))
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
"forwarding as communication returned status %d (error: "
@@ -1349,29 +1411,61 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
return SendErrorResponse(69);
StreamString response;
- response.Printf("QC%" PRIx64, thread->GetID());
+ response.PutCString("QC");
+ AppendThreadIDToResponse(response, m_current_process->GetID(),
+ thread->GetID());
return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
StopSTDIOForwarding();
- if (!m_current_process) {
+ if (m_debugged_processes.empty()) {
LLDB_LOG(log, "No debugged process found.");
return PacketResult::Success;
}
- Status error = m_current_process->Kill();
+ for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end();
+ ++it) {
+ LLDB_LOG(log, "Killing process {0}", it->first);
+ Status error = it->second->Kill();
+ if (error.Fail())
+ LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", it->first,
+ error);
+ }
+
+ // The response to kill packet is undefined per the spec. LLDB
+ // follows the same rules as for continue packets, i.e. no response
+ // in all-stop mode, and "OK" in non-stop mode; in both cases this
+ // is followed by the actual stop reason.
+ return SendContinueSuccessResponse();
+}
+
+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())
- LLDB_LOG(log, "Failed to kill debugged process {0}: {1}",
- m_current_process->GetID(), error);
+ return SendErrorResponse(error.ToError());
- // No OK response for kill packet.
- // return SendOKResponse ();
+ // OK response is sent when the process dies.
+ m_vkilled_processes.insert(pid);
return PacketResult::Success;
}
@@ -1425,7 +1519,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Ensure we have a native process.
@@ -1500,13 +1594,14 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
return SendErrorResponse(0x38);
}
- // Don't send an "OK" packet; response is the stopped/exited message.
- return PacketResult::Success;
+ // Don't send an "OK" packet, except in non-stop mode;
+ // otherwise, the response is the stopped/exited message.
+ return SendContinueSuccessResponse();
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
@@ -1540,15 +1635,15 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
}
LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
- // No response required from continue.
- return PacketResult::Success;
+
+ return SendContinueSuccessResponse();
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vCont_actions(
StringExtractorGDBRemote &packet) {
StreamString response;
- response.Printf("vCont;c;C;s;S");
+ response.Printf("vCont;c;C;s;S;t");
return SendPacketNoLock(response.GetString());
}
@@ -1556,7 +1651,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont_actions(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vCont(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
__FUNCTION__);
@@ -1570,24 +1665,16 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont(
return SendIllFormedResponse(packet, "Missing action from vCont package");
}
- // Check if this is all continue (no options or ";c").
- if (::strcmp(packet.Peek(), ";c") == 0) {
- // Move past the ';', then do a simple 'c'.
- packet.SetFilePos(packet.GetFilePos() + 1);
- return Handle_c(packet);
- } else if (::strcmp(packet.Peek(), ";s") == 0) {
+ if (::strcmp(packet.Peek(), ";s") == 0) {
// Move past the ';', then do a simple 's'.
packet.SetFilePos(packet.GetFilePos() + 1);
return Handle_s(packet);
+ } else if (m_non_stop && ::strcmp(packet.Peek(), ";t") == 0) {
+ // TODO: add full support for "t" action
+ return SendOKResponse();
}
- // Ensure we have a native process.
- if (!m_continue_process) {
- LLDB_LOG(log, "no debugged process");
- return SendErrorResponse(0x36);
- }
-
- ResumeActionList thread_actions;
+ std::unordered_map<lldb::pid_t, ResumeActionList> thread_actions;
while (packet.GetBytesLeft() && *packet.Peek() == ';') {
// Skip the semi-colon.
@@ -1625,43 +1712,78 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont(
thread_action.state = eStateStepping;
break;
+ case 't':
+ // Stop
+ thread_action.state = eStateSuspended;
+ break;
+
default:
return SendIllFormedResponse(packet, "Unsupported vCont action");
break;
}
+ lldb::pid_t pid = StringExtractorGDBRemote::AllProcesses;
+ lldb::tid_t tid = StringExtractorGDBRemote::AllThreads;
+
// Parse out optional :{thread-id} value.
if (packet.GetBytesLeft() && (*packet.Peek() == ':')) {
// Consume the separator.
packet.GetChar();
- llvm::Expected<lldb::tid_t> tid_ret =
- ReadTid(packet, /*allow_all=*/true, m_continue_process->GetID());
- if (!tid_ret)
- return SendErrorResponse(tid_ret.takeError());
+ auto pid_tid = packet.GetPidTid(StringExtractorGDBRemote::AllProcesses);
+ if (!pid_tid)
+ return SendIllFormedResponse(packet, "Malformed thread-id");
+
+ pid = pid_tid->first;
+ tid = pid_tid->second;
+ }
- thread_action.tid = tid_ret.get();
- if (thread_action.tid == StringExtractorGDBRemote::AllThreads)
- thread_action.tid = LLDB_INVALID_THREAD_ID;
+ if (pid == StringExtractorGDBRemote::AllProcesses) {
+ if (m_debugged_processes.size() > 1)
+ return SendIllFormedResponse(
+ packet, "Resuming multiple processes not supported yet");
+ if (!m_continue_process) {
+ LLDB_LOG(log, "no debugged process");
+ return SendErrorResponse(0x36);
+ }
+ pid = m_continue_process->GetID();
}
- thread_actions.Append(thread_action);
+ if (tid == StringExtractorGDBRemote::AllThreads)
+ tid = LLDB_INVALID_THREAD_ID;
+
+ thread_action.tid = tid;
+
+ thread_actions[pid].Append(thread_action);
}
- Status error = m_continue_process->Resume(thread_actions);
- if (error.Fail()) {
- LLDB_LOG(log, "vCont failed for process {0}: {1}",
- m_continue_process->GetID(), error);
- return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ assert(thread_actions.size() >= 1);
+ if (thread_actions.size() > 1)
+ return SendIllFormedResponse(
+ packet, "Resuming multiple processes not supported yet");
+
+ for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) {
+ auto process_it = m_debugged_processes.find(x.first);
+ if (process_it == m_debugged_processes.end()) {
+ LLDB_LOG(log, "vCont failed for process {0}: process not debugged",
+ x.first);
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
+
+ Status error = process_it->second->Resume(x.second);
+ if (error.Fail()) {
+ LLDB_LOG(log, "vCont failed for process {0}: {1}", x.first, error);
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
+
+ LLDB_LOG(log, "continued process {0}", x.first);
}
- LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
- // No response required from vCont.
- return PacketResult::Success;
+ return SendContinueSuccessResponse();
}
void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
LLDB_LOG(log, "setting current thread id to {0}", tid);
m_current_tid = tid;
@@ -1670,7 +1792,7 @@ void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
}
void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
LLDB_LOG(log, "setting continue thread id to {0}", tid);
m_continue_tid = tid;
@@ -1681,17 +1803,47 @@ GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
StringExtractorGDBRemote &packet) {
// Handle the $? gdbremote command.
+ if (m_non_stop) {
+ // Clear the notification queue first, except for pending exit
+ // notifications.
+ llvm::erase_if(m_stop_notification_queue, [](const std::string &x) {
+ return x.front() != 'W' && x.front() != 'X';
+ });
+
+ if (m_current_process) {
+ // Queue stop reply packets for all active threads. Start with
+ // the current thread (for clients that don't actually support multiple
+ // stop reasons).
+ NativeThreadProtocol *thread = m_current_process->GetCurrentThread();
+ if (thread)
+ m_stop_notification_queue.push_back(
+ PrepareStopReplyPacketForThread(*thread).GetString().str());
+ EnqueueStopReplyPackets(thread ? thread->GetID()
+ : LLDB_INVALID_THREAD_ID);
+ }
+
+ // If the notification queue is empty (i.e. everything is running), send OK.
+ if (m_stop_notification_queue.empty())
+ return SendOKResponse();
+
+ // Send the first item from the new notification queue synchronously.
+ return SendPacketNoLock(m_stop_notification_queue.front());
+ }
+
// If no process, indicate error
if (!m_current_process)
return SendErrorResponse(02);
- return SendStopReasonForState(m_current_process->GetState());
+ return SendStopReasonForState(*m_current_process,
+ m_current_process->GetState(),
+ /*force_synchronous=*/true);
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
- lldb::StateType process_state) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ NativeProcessProtocol &process, lldb::StateType process_state,
+ bool force_synchronous) {
+ Log *log = GetLog(LLDBLog::Process);
switch (process_state) {
case eStateAttaching:
@@ -1706,22 +1858,21 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
case eStateSuspended:
case eStateStopped:
case eStateCrashed: {
- assert(m_current_process != nullptr);
- lldb::tid_t tid = m_current_process->GetCurrentThreadID();
+ lldb::tid_t tid = process.GetCurrentThreadID();
// Make sure we set the current thread so g and p packets return the data
// the gdb will expect.
SetCurrentThreadID(tid);
- return SendStopReplyPacketForThread(tid);
+ return SendStopReplyPacketForThread(process, tid, force_synchronous);
}
case eStateInvalid:
case eStateUnloaded:
case eStateExited:
- return SendWResponse(m_current_process);
+ return SendWResponse(&process);
default:
LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}",
- m_current_process->GetID(), process_state);
+ process.GetID(), process_state);
break;
}
@@ -1819,38 +1970,38 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
return SendPacketNoLock(response.GetString());
}
+void GDBRemoteCommunicationServerLLGS::AddProcessThreads(
+ StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any) {
+ Log *log = GetLog(LLDBLog::Thread);
+
+ lldb::pid_t pid = process.GetID();
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return;
+
+ LLDB_LOG(log, "iterating over threads of process {0}", process.GetID());
+ for (NativeThreadProtocol &thread : process.Threads()) {
+ LLDB_LOG(log, "iterated thread tid={0}", thread.GetID());
+ response.PutChar(had_any ? ',' : 'm');
+ AppendThreadIDToResponse(response, pid, thread.GetID());
+ had_any = true;
+ }
+}
+
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_current_process ||
- (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
- LLDB_LOG(log, "no process ({0}), returning OK",
- m_current_process ? "invalid process id"
- : "null m_current_process");
- return SendOKResponse();
- }
+ assert(m_debugged_processes.size() == 1 ||
+ bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::multiprocess));
+ bool had_any = false;
StreamGDBRemote response;
- response.PutChar('m');
- LLDB_LOG(log, "starting thread iteration");
- NativeThreadProtocol *thread;
- uint32_t thread_index;
- for (thread_index = 0,
- thread = m_current_process->GetThreadAtIndex(thread_index);
- thread; ++thread_index,
- thread = m_current_process->GetThreadAtIndex(thread_index)) {
- LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
- thread->GetID());
- if (thread_index > 0)
- response.PutChar(',');
- response.Printf("%" PRIx64, thread->GetID());
- }
+ for (auto &pid_ptr : m_debugged_processes)
+ AddProcessThreads(response, *pid_ptr.second, had_any);
- LLDB_LOG(log, "finished thread iteration");
+ if (!had_any)
+ return SendOKResponse();
return SendPacketNoLock(response.GetString());
}
@@ -1864,7 +2015,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Move past packet name.
packet.SetFilePos(strlen("g"));
@@ -1919,7 +2070,7 @@ GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Parse out the register number from the request.
packet.SetFilePos(strlen("p"));
@@ -1995,7 +2146,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Ensure there is more content.
if (packet.GetBytesLeft() < 1)
@@ -2075,7 +2226,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Parse out which variant of $H is requested.
packet.SetFilePos(strlen("H"));
@@ -2166,7 +2317,7 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Fail if we don't have a current process.
if (!m_current_process ||
@@ -2202,7 +2353,7 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_interrupt(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
// Fail if we don't have a current process.
if (!m_current_process ||
@@ -2228,7 +2379,7 @@ GDBRemoteCommunicationServerLLGS::Handle_interrupt(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_memory_read(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (!m_current_process ||
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
@@ -2308,7 +2459,7 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (!m_current_process ||
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
@@ -2357,7 +2508,7 @@ GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (!m_current_process ||
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
@@ -2385,7 +2536,7 @@ GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
if (!m_current_process ||
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
@@ -2465,7 +2616,7 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Currently only the NativeProcessProtocol knows if it can handle a
// qMemoryRegionInfoSupported request, but we're not guaranteed to be
@@ -2498,7 +2649,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Ensure we have a process.
if (!m_current_process ||
@@ -2580,7 +2731,7 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
if (!m_current_process ||
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOG(log, "failed, no process available");
return SendErrorResponse(0x15);
}
@@ -2652,7 +2803,7 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
m_current_process->SetBreakpoint(addr, size, want_hardware);
if (error.Success())
return SendOKResponse();
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}",
m_current_process->GetID(), error);
return SendErrorResponse(0x09);
@@ -2662,7 +2813,7 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
addr, size, watch_flags, want_hardware);
if (error.Success())
return SendOKResponse();
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}",
m_current_process->GetID(), error);
return SendErrorResponse(0x09);
@@ -2674,7 +2825,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
if (!m_current_process ||
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOG(log, "failed, no process available");
return SendErrorResponse(0x15);
}
@@ -2740,7 +2891,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
m_current_process->RemoveBreakpoint(addr, want_hardware);
if (error.Success())
return SendOKResponse();
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}",
m_current_process->GetID(), error);
return SendErrorResponse(0x09);
@@ -2749,7 +2900,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
const Status error = m_current_process->RemoveWatchpoint(addr);
if (error.Success())
return SendOKResponse();
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}",
m_current_process->GetID(), error);
return SendErrorResponse(0x09);
@@ -2758,7 +2909,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
// Ensure we have a process.
if (!m_continue_process ||
@@ -2803,8 +2954,9 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
return SendErrorResponse(0x49);
}
- // No response here - the stop or exit will come from the resulting action.
- return PacketResult::Success;
+ // No response here, unless in non-stop mode.
+ // Otherwise, the stop or exit will come from the resulting action.
+ return SendContinueSuccessResponse();
}
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
@@ -2815,7 +2967,7 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"No thread available");
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
// Get the register context for the first thread.
NativeRegisterContext &reg_context = thread->GetRegisterContext();
@@ -3032,7 +3184,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qXfer(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Move past packet name.
packet.SetFilePos(strlen("QSaveRegisterState"));
@@ -3052,7 +3204,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
NativeRegisterContext& reg_context = thread->GetRegisterContext();
// Save registers to a buffer.
- DataBufferSP register_data_sp;
+ WritableDataBufferSP register_data_sp;
Status error = reg_context.ReadAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
@@ -3080,7 +3232,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Parse out save id.
packet.SetFilePos(strlen("QRestoreRegisterState:"));
@@ -3141,7 +3293,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vAttach(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Consume the ';' after vAttach.
packet.SetFilePos(strlen("vAttach"));
@@ -3171,13 +3323,16 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
}
// Notify we attached by sending a stop packet.
- return SendStopReasonForState(m_current_process->GetState());
+ assert(m_current_process);
+ return SendStopReasonForState(*m_current_process,
+ m_current_process->GetState(),
+ /*force_synchronous=*/false);
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Consume the ';' after the identifier.
packet.SetFilePos(strlen("vAttachWait"));
@@ -3201,7 +3356,10 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
}
// Notify we attached by sending a stop packet.
- return SendStopReasonForState(m_current_process->GetState());
+ assert(m_current_process);
+ return SendStopReasonForState(*m_current_process,
+ m_current_process->GetState(),
+ /*force_synchronous=*/false);
}
GDBRemoteCommunication::PacketResult
@@ -3213,7 +3371,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Consume the ';' after the identifier.
packet.SetFilePos(strlen("vAttachOrWait"));
@@ -3237,13 +3395,16 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait(
}
// Notify we attached by sending a stop packet.
- return SendStopReasonForState(m_current_process->GetState());
+ assert(m_current_process);
+ return SendStopReasonForState(*m_current_process,
+ m_current_process->GetState(),
+ /*force_synchronous=*/false);
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vRun(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
llvm::StringRef s = packet.GetStringRef();
if (!s.consume_front("vRun;"))
@@ -3265,8 +3426,12 @@ GDBRemoteCommunicationServerLLGS::Handle_vRun(
m_process_launch_info.GetExecutableFile().SetFile(
m_process_launch_info.GetArguments()[0].ref(), FileSpec::Style::native);
m_process_launch_error = LaunchProcess();
- if (m_process_launch_error.Success())
- return SendStopReasonForState(m_current_process->GetState());
+ if (m_process_launch_error.Success()) {
+ assert(m_current_process);
+ return SendStopReasonForState(*m_current_process,
+ m_current_process->GetState(),
+ /*force_synchronous=*/true);
+ }
LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
}
return SendErrorResponse(8);
@@ -3274,6 +3439,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vRun(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
+ Log *log = GetLog(LLDBLog::Process);
StopSTDIOForwarding();
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
@@ -3297,6 +3463,9 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
for (auto it = m_debugged_processes.begin();
it != m_debugged_processes.end();) {
if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) {
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s detaching %" PRId64,
+ __FUNCTION__, it->first);
if (llvm::Error e = it->second->Detach().ToError())
detach_error = llvm::joinErrors(std::move(detach_error), std::move(e));
else {
@@ -3322,7 +3491,11 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
+
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(50);
packet.SetFilePos(strlen("qThreadStopInfo"));
const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
@@ -3333,13 +3506,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
__FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x15);
}
- return SendStopReplyPacketForThread(tid);
+ return SendStopReplyPacketForThread(*m_current_process, tid,
+ /*force_synchronous=*/true);
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
StringExtractorGDBRemote &) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
// Ensure we have a debugged process.
if (!m_current_process ||
@@ -3455,7 +3629,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qMemTags(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Ensure we have a process.
if (!m_current_process ||
@@ -3536,7 +3710,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemTags(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_QMemTags(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Ensure we have a process.
if (!m_current_process ||
@@ -3656,8 +3830,91 @@ GDBRemoteCommunicationServerLLGS::Handle_qSaveCore(
return SendPacketNoLock(response.GetString());
}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QNonStop(
+ StringExtractorGDBRemote &packet) {
+ StringRef packet_str{packet.GetStringRef()};
+ assert(packet_str.startswith("QNonStop:"));
+ packet_str.consume_front("QNonStop:");
+ if (packet_str == "0") {
+ m_non_stop = false;
+ // TODO: stop all threads
+ } else if (packet_str == "1") {
+ m_non_stop = true;
+ } else
+ return SendErrorResponse(Status("Invalid QNonStop packet"));
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vStopped(
+ StringExtractorGDBRemote &packet) {
+ // 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())
+ 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());
+ // If this was the last notification and all the processes exited,
+ // terminate the server.
+ if (m_debugged_processes.empty()) {
+ m_exit_now = true;
+ m_mainloop.RequestTermination();
+ }
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vCtrlC(
+ StringExtractorGDBRemote &packet) {
+ if (!m_non_stop)
+ return SendErrorResponse(Status("vCtrl is only valid in non-stop mode"));
+
+ PacketResult interrupt_res = Handle_interrupt(packet);
+ // If interrupting the process failed, pass the result through.
+ if (interrupt_res != PacketResult::Success)
+ return interrupt_res;
+ // Otherwise, vCtrlC should issue an OK response (normal interrupts do not).
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_T(StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(strlen("T"));
+ auto pid_tid = packet.GetPidTid(m_current_process ? m_current_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;
+
+ // Technically, this would also be caught by the PID check but let's be more
+ // explicit about the error.
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(llvm::make_error<StringError>(
+ inconvertibleErrorCode(), "No current process and no PID provided"));
+
+ // Check the process ID and find respective process instance.
+ auto new_process_it = m_debugged_processes.find(pid);
+ if (new_process_it == m_debugged_processes.end())
+ return SendErrorResponse(1);
+
+ // Check the thread ID
+ if (!new_process_it->second->GetThreadByID(tid))
+ return SendErrorResponse(2);
+
+ return SendOKResponse();
+}
+
void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Tell the stdio connection to shut down.
if (m_stdio_communication.IsConnected()) {
@@ -3701,7 +3958,7 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
return m_current_process->GetThreadByID(current_tid);
}
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ Log *log = GetLog(LLDBLog::Thread);
// Parse out the ';'.
if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
@@ -3752,7 +4009,7 @@ uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() {
}
void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size());
m_xfer_buffer_map.clear();
@@ -3799,38 +4056,6 @@ std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue(
return result;
}
-llvm::Expected<lldb::tid_t> GDBRemoteCommunicationServerLLGS::ReadTid(
- StringExtractorGDBRemote &packet, bool allow_all, lldb::pid_t default_pid) {
- assert(m_current_process);
- assert(m_current_process->GetID() != LLDB_INVALID_PROCESS_ID);
-
- auto pid_tid = packet.GetPidTid(default_pid);
- if (!pid_tid)
- return llvm::make_error<StringError>(inconvertibleErrorCode(),
- "Malformed thread-id");
-
- lldb::pid_t pid = pid_tid->first;
- lldb::tid_t tid = pid_tid->second;
-
- if (!allow_all && pid == StringExtractorGDBRemote::AllProcesses)
- return llvm::make_error<StringError>(
- inconvertibleErrorCode(),
- llvm::formatv("PID value {0} not allowed", pid == 0 ? 0 : -1));
-
- if (!allow_all && tid == StringExtractorGDBRemote::AllThreads)
- return llvm::make_error<StringError>(
- inconvertibleErrorCode(),
- llvm::formatv("TID value {0} not allowed", tid == 0 ? 0 : -1));
-
- if (pid != StringExtractorGDBRemote::AllProcesses) {
- if (pid != m_current_process->GetID())
- return llvm::make_error<StringError>(
- inconvertibleErrorCode(), llvm::formatv("PID {0} not debugged", pid));
- }
-
- return tid;
-}
-
std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
const llvm::ArrayRef<llvm::StringRef> client_features) {
std::vector<std::string> ret =
@@ -3839,6 +4064,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
"QThreadSuffixSupported+",
"QListThreadsInStopReply+",
"qXfer:features:read+",
+ "QNonStop+",
});
// report server-only features
@@ -3893,6 +4119,21 @@ void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions(
process.SetEnabledExtensions(flags);
}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendContinueSuccessResponse() {
+ // TODO: how to handle forwarding in non-stop mode?
+ StartSTDIOForwarding();
+ return m_non_stop ? SendOKResponse() : PacketResult::Success;
+}
+
+void GDBRemoteCommunicationServerLLGS::AppendThreadIDToResponse(
+ Stream &response, lldb::pid_t pid, lldb::tid_t tid) {
+ if (bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::multiprocess))
+ response.Format("p{0:x-}.", pid);
+ response.Format("{0:x-}", tid);
+}
+
std::string
lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg,
bool reverse_connect) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 17ee4130dc34..5187a953f957 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -11,6 +11,7 @@
#include <mutex>
#include <unordered_map>
+#include <unordered_set>
#include "lldb/Core/Communication.h"
#include "lldb/Host/MainLoop.h"
@@ -95,6 +96,7 @@ protected:
std::recursive_mutex m_debugged_process_mutex;
std::unordered_map<lldb::pid_t, std::unique_ptr<NativeProcessProtocol>>
m_debugged_processes;
+ std::unordered_set<lldb::pid_t> m_vkilled_processes;
Communication m_stdio_communication;
MainLoop::ReadHandleUP m_stdio_handle_up;
@@ -106,6 +108,8 @@ protected:
uint32_t m_next_saved_registers_id = 1;
bool m_thread_suffix_supported = false;
bool m_list_threads_in_stop_reply = false;
+ bool m_non_stop = false;
+ std::deque<std::string> m_stop_notification_queue;
NativeProcessProtocol::Extension m_extensions_supported = {};
@@ -113,12 +117,22 @@ protected:
PacketResult SendWResponse(NativeProcessProtocol *process);
- PacketResult SendStopReplyPacketForThread(lldb::tid_t tid);
+ StreamString PrepareStopReplyPacketForThread(NativeThreadProtocol &thread);
- PacketResult SendStopReasonForState(lldb::StateType process_state);
+ PacketResult SendStopReplyPacketForThread(NativeProcessProtocol &process,
+ lldb::tid_t tid,
+ bool force_synchronous);
+
+ PacketResult SendStopReasonForState(NativeProcessProtocol &process,
+ lldb::StateType process_state,
+ bool force_synchronous);
+
+ void EnqueueStopReplyPackets(lldb::tid_t thread_to_skip);
PacketResult Handle_k(StringExtractorGDBRemote &packet);
+ PacketResult Handle_vKill(StringExtractorGDBRemote &packet);
+
PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
PacketResult Handle_qC(StringExtractorGDBRemote &packet);
@@ -145,6 +159,9 @@ protected:
PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet);
+ void AddProcessThreads(StreamGDBRemote &response,
+ NativeProcessProtocol &process, bool &had_any);
+
PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet);
PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
@@ -217,12 +234,20 @@ protected:
PacketResult Handle_qSaveCore(StringExtractorGDBRemote &packet);
+ PacketResult Handle_QNonStop(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_vStopped(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_vCtrlC(StringExtractorGDBRemote &packet);
+
PacketResult Handle_g(StringExtractorGDBRemote &packet);
PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet);
PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet);
+ PacketResult Handle_T(StringExtractorGDBRemote &packet);
+
void SetCurrentThreadID(lldb::tid_t tid);
lldb::tid_t GetCurrentThreadID() const;
@@ -241,9 +266,16 @@ protected:
static std::string XMLEncodeAttributeValue(llvm::StringRef value);
- virtual std::vector<std::string> HandleFeatures(
+ std::vector<std::string> HandleFeatures(
const llvm::ArrayRef<llvm::StringRef> client_features) override;
+ // Provide a response for successful continue action, i.e. send "OK"
+ // in non-stop mode, no response otherwise.
+ PacketResult SendContinueSuccessResponse();
+
+ void AppendThreadIDToResponse(Stream &response, lldb::pid_t pid,
+ lldb::tid_t tid);
+
private:
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml();
@@ -269,15 +301,6 @@ private:
void StopSTDIOForwarding();
- // Read thread-id from packet. If the thread-id is correct, returns it.
- // Otherwise, returns the error.
- //
- // If allow_all is true, then the pid/tid value of -1 ('all') will be allowed.
- // In any case, the function assumes that exactly one inferior is being
- // debugged and rejects pid values that do no match that inferior.
- llvm::Expected<lldb::tid_t> ReadTid(StringExtractorGDBRemote &packet,
- bool allow_all, lldb::pid_t default_pid);
-
// Call SetEnabledExtensions() with appropriate flags on the process.
void SetEnabledExtensions(NativeProcessProtocol &process);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index a63b98edec55..6f137d09fee4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -30,6 +30,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/GDBRemote.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
@@ -178,7 +179,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
if (hostname.empty())
hostname = "127.0.0.1";
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ Log *log = GetLog(LLDBLog::Platform);
LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
*port);
@@ -187,8 +188,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
debugserver_launch_info.SetMonitorProcessCallback(
std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
- this, std::placeholders::_1),
- false);
+ this, std::placeholders::_1));
std::ostringstream url;
// debugserver does not accept the URL scheme prefix.
@@ -228,7 +228,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
// Spawn a local debugserver as a platform so we can then attach or launch a
// process...
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ Log *log = GetLog(LLDBLog::Platform);
LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called",
__FUNCTION__);
@@ -244,7 +244,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
else if (name.equals("port")) {
// Make the Optional valid so we can use its value
port = 0;
- value.getAsInteger(0, port.getValue());
+ value.getAsInteger(0, *port);
}
}
@@ -516,12 +516,11 @@ GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
return SendPacketNoLock(response.GetString());
}
-bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
+void GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
lldb::pid_t pid) {
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
m_port_map.FreePortForProcess(pid);
m_spawned_pids.erase(pid);
- return true;
}
Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
@@ -532,11 +531,9 @@ Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
// specify the process monitor if not already set. This should generally be
// what happens since we need to reap started processes.
if (!m_process_launch_info.GetMonitorProcessCallback())
- m_process_launch_info.SetMonitorProcessCallback(
- std::bind(
- &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
- this, std::placeholders::_1),
- false);
+ m_process_launch_info.SetMonitorProcessCallback(std::bind(
+ &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this,
+ std::placeholders::_1));
Status error = Host::LaunchProcess(m_process_launch_info);
if (!error.Success()) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 6b964da4a279..8dbd5ba942f8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -131,7 +131,7 @@ protected:
private:
bool KillSpawnedProcess(lldb::pid_t pid);
- bool DebugserverProcessReaped(lldb::pid_t pid);
+ void DebugserverProcessReaped(lldb::pid_t pid);
static const FileSpec &GetDomainSocketDir();
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 1b66e8c16281..7ad4f4968eac 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -517,7 +517,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
}
bool GDBRemoteRegisterContext::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
+ lldb::WritableDataBufferSP &data_sp) {
ExecutionContext exe_ctx(CalculateThread());
Process *process = exe_ctx.GetProcessPtr();
@@ -536,9 +536,13 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
InvalidateAllRegisters();
- if (use_g_packet &&
- (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
- return true;
+ if (use_g_packet) {
+ if (DataBufferSP data_buffer =
+ gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
+ data_sp = std::make_shared<DataBufferHeap>(*data_buffer);
+ return true;
+ }
+ }
// We're going to read each register
// individually and store them as binary data in a buffer.
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 83c809c5aab6..d185cb5aede1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -65,7 +65,7 @@ public:
bool WriteRegister(const RegisterInfo *reg_info,
const RegisterValue &value) override;
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override;
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 82357cd117d7..fe6a3f9ed6c1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -59,6 +59,7 @@
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
@@ -73,7 +74,6 @@
#include "GDBRemoteRegisterContext.h"
#include "GDBRemoteRegisterFallback.h"
-#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
@@ -208,6 +208,10 @@ std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() {
return std::chrono::seconds(GetGlobalPluginProperties().GetPacketTimeout());
}
+ArchSpec ProcessGDBRemote::GetSystemArchitecture() {
+ return m_gdb_comm.GetHostArchitecture();
+}
+
bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) {
if (plugin_specified_by_name)
@@ -252,7 +256,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(),
m_max_memory_size(0), m_remote_stub_max_memory_size(0),
m_addr_to_mmap_size(), m_thread_create_bp_sp(),
- m_waiting_for_attach(false), m_destroy_tried_resuming(false),
+ m_waiting_for_attach(false),
m_command_sp(), m_breakpoint_pc_offset(0),
m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false),
m_erased_flash_ranges(), m_vfork_in_progress(false) {
@@ -406,13 +410,13 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
}
if (target_definition_fspec) {
// See if we can get register definitions from a python file
- if (ParsePythonTargetDefinition(target_definition_fspec)) {
+ if (ParsePythonTargetDefinition(target_definition_fspec))
return;
- } else {
- StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
- stream_sp->Printf("ERROR: target description file %s failed to parse.\n",
- target_definition_fspec.GetPath().c_str());
- }
+
+ Debugger::ReportError("target description file " +
+ target_definition_fspec.GetPath() +
+ " failed to parse",
+ GetTarget().GetDebugger().GetID());
}
const ArchSpec &target_arch = GetTarget().GetArchitecture();
@@ -587,8 +591,10 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
if (!module_sp) {
// Force a an external lookup, if that tool is available.
- if (!module_spec.GetSymbolFileSpec())
- Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+ if (!module_spec.GetSymbolFileSpec()) {
+ Status error;
+ Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
+ }
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
module_sp = std::make_shared<Module>(module_spec);
@@ -606,7 +612,7 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
}
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log = GetLog(LLDBLog::DynamicLoader);
if (module_sp.get()) {
target.GetImages().AppendIfNeeded(module_sp, false);
@@ -948,12 +954,23 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
m_gdb_comm.GetVAttachOrWaitSupported();
m_gdb_comm.EnableErrorStringInPacket();
- size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
- for (size_t idx = 0; idx < num_cmds; idx++) {
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse(
- GetExtraStartupCommands().GetArgumentAtIndex(idx), response);
+ // First dispatch any commands from the platform:
+ auto handle_cmds = [&] (const Args &args) -> void {
+ for (const Args::ArgEntry &entry : args) {
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse(
+ entry.c_str(), response);
+ }
+ };
+
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (platform_sp) {
+ handle_cmds(platform_sp->GetExtraStartupCommands());
}
+
+ // Then dispatch any process commands:
+ handle_cmds(GetExtraStartupCommands());
+
return error;
}
@@ -1667,7 +1684,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
for (const auto &pair : expedited_register_map) {
StringExtractor reg_value_extractor(pair.second);
- DataBufferSP buffer_sp(new DataBufferHeap(
+ WritableDataBufferSP buffer_sp(new DataBufferHeap(
reg_value_extractor.GetStringRef().size() / 2, 0));
reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
uint32_t lldb_regnum =
@@ -2046,7 +2063,8 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
bytes.SetFilePos(0);
const size_t byte_size = bytes.GetStringRef().size() / 2;
- DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ WritableDataBufferSP data_buffer_sp(
+ new DataBufferHeap(byte_size, 0));
const size_t bytes_copied =
bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
if (bytes_copied == byte_size)
@@ -2208,7 +2226,8 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
if (!addr_str.getAsInteger(0, mem_cache_addr)) {
StringExtractor bytes(bytes_str);
const size_t byte_size = bytes.GetBytesLeft() / 2;
- DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ WritableDataBufferSP data_buffer_sp(
+ new DataBufferHeap(byte_size, 0));
const size_t bytes_copied =
bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
if (bytes_copied == byte_size)
@@ -2379,110 +2398,6 @@ Status ProcessGDBRemote::DoDestroy() {
Log *log = GetLog(GDBRLog::Process);
LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy()");
- // There is a bug in older iOS debugservers where they don't shut down the
- // process they are debugging properly. If the process is sitting at a
- // breakpoint or an exception, this can cause problems with restarting. So
- // we check to see if any of our threads are stopped at a breakpoint, and if
- // so we remove all the breakpoints, resume the process, and THEN destroy it
- // again.
- //
- // Note, we don't have a good way to test the version of debugserver, but I
- // happen to know that the set of all the iOS debugservers which don't
- // support GetThreadSuffixSupported() and that of the debugservers with this
- // bug are equal. There really should be a better way to test this!
- //
- // We also use m_destroy_tried_resuming to make sure we only do this once, if
- // we resume and then halt and get called here to destroy again and we're
- // still at a breakpoint or exception, then we should just do the straight-
- // forward kill.
- //
- // And of course, if we weren't able to stop the process by the time we get
- // here, it isn't necessary (or helpful) to do any of this.
-
- if (!m_gdb_comm.GetThreadSuffixSupported() &&
- m_public_state.GetValue() != eStateRunning) {
- PlatformSP platform_sp = GetTarget().GetPlatform();
-
- if (platform_sp && platform_sp->GetName() &&
- platform_sp->GetName().GetStringRef() ==
- PlatformRemoteiOS::GetPluginNameStatic()) {
- if (m_destroy_tried_resuming) {
- if (log)
- log->PutCString("ProcessGDBRemote::DoDestroy() - Tried resuming to "
- "destroy once already, not doing it again.");
- } else {
- // At present, the plans are discarded and the breakpoints disabled
- // Process::Destroy, but we really need it to happen here and it
- // doesn't matter if we do it twice.
- m_thread_list.DiscardThreadPlans();
- DisableAllBreakpointSites();
-
- bool stop_looks_like_crash = false;
- ThreadList &threads = GetThreadList();
-
- {
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; i++) {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
- StopReason reason = eStopReasonInvalid;
- if (stop_info_sp)
- reason = stop_info_sp->GetStopReason();
- if (reason == eStopReasonBreakpoint ||
- reason == eStopReasonException) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
- " stopped with reason: %s.",
- thread_sp->GetProtocolID(),
- stop_info_sp->GetDescription());
- stop_looks_like_crash = true;
- break;
- }
- }
- }
-
- if (stop_looks_like_crash) {
- if (log)
- log->PutCString("ProcessGDBRemote::DoDestroy() - Stopped at a "
- "breakpoint, continue and then kill.");
- m_destroy_tried_resuming = true;
-
- // If we are going to run again before killing, it would be good to
- // suspend all the threads before resuming so they won't get into
- // more trouble. Sadly, for the threads stopped with the breakpoint
- // or exception, the exception doesn't get cleared if it is
- // suspended, so we do have to run the risk of letting those threads
- // proceed a bit.
-
- {
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; i++) {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
- StopReason reason = eStopReasonInvalid;
- if (stop_info_sp)
- reason = stop_info_sp->GetStopReason();
- if (reason != eStopReasonBreakpoint &&
- reason != eStopReasonException) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::DoDestroy() - Suspending "
- "thread: 0x%4.4" PRIx64 " before running.",
- thread_sp->GetProtocolID());
- thread_sp->SetResumeState(eStateSuspended);
- }
- }
- }
- Resume();
- return Destroy(false);
- }
- }
- }
- }
-
// Interrupt if our inferior is running...
int exit_status = SIGABRT;
std::string exit_string;
@@ -2919,8 +2834,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
uint32_t permissions,
Status &error) {
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_EXPRESSIONS));
+ Log *log = GetLog(LLDBLog::Process | LLDBLog::Expressions);
addr_t allocated_addr = LLDB_INVALID_ADDRESS;
if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo) {
@@ -2962,8 +2876,8 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
return allocated_addr;
}
-Status ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
Status error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
return error;
@@ -3366,7 +3280,7 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
const std::weak_ptr<ProcessGDBRemote> this_wp =
std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
debugserver_launch_info.SetMonitorProcessCallback(
- std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false);
+ std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3));
debugserver_launch_info.SetUserID(process_info.GetUserID());
#if defined(__APPLE__)
@@ -3445,16 +3359,14 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
return error;
}
-bool ProcessGDBRemote::MonitorDebugserverProcess(
+void ProcessGDBRemote::MonitorDebugserverProcess(
std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
- bool exited, // True if the process did exit
int signo, // Zero for no signal
int exit_status // Exit value of process if signal is zero
) {
// "debugserver_pid" argument passed in is the process ID for debugserver
// that we are tracking...
Log *log = GetLog(GDBRLog::Process);
- const bool handled = true;
LLDB_LOGF(log,
"ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
@@ -3465,7 +3377,7 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
LLDB_LOGF(log, "ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
static_cast<void *>(process_sp.get()));
if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
- return handled;
+ return;
// Sleep for a half a second to make sure our inferior process has time to
// set its exit status before we set it incorrectly when both the debugserver
@@ -3499,7 +3411,6 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
// Debugserver has exited we need to let our ProcessGDBRemote know that it no
// longer has a debugserver instance
process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- return handled;
}
void ProcessGDBRemote::KillDebugserverProcess() {
@@ -3541,11 +3452,12 @@ bool ProcessGDBRemote::StartAsyncThread() {
// Create a thread that watches our internal state and controls which
// events make it to clients (into the DCProcess event queue).
- llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
- "<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this);
+ llvm::Expected<HostThread> async_thread =
+ ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", [this] {
+ return ProcessGDBRemote::AsyncThread();
+ });
if (!async_thread) {
- LLDB_LOG_ERROR(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
- async_thread.takeError(),
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
"failed to launch host thread: {}");
return false;
}
@@ -3581,14 +3493,10 @@ void ProcessGDBRemote::StopAsyncThread() {
__FUNCTION__);
}
-thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
- ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
-
+thread_result_t ProcessGDBRemote::AsyncThread() {
Log *log = GetLog(GDBRLog::Process);
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread starting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread starting...",
+ __FUNCTION__, GetID());
EventSP event_sp;
@@ -3604,19 +3512,19 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// fetch loop.
bool done = false;
- while (!done && process->GetPrivateState() != eStateExited) {
+ while (!done && GetPrivateState() != eStateExited) {
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") listener.WaitForEvent (NULL, event_sp)...",
- __FUNCTION__, arg, process->GetID());
+ __FUNCTION__, GetID());
- if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
+ if (m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
- if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
+ if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") Got an event of type: %d...",
- __FUNCTION__, arg, process->GetID(), event_type);
+ __FUNCTION__, GetID(), event_type);
switch (event_type) {
case eBroadcastBitAsyncContinue: {
@@ -3628,39 +3536,39 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
(const char *)continue_packet->GetBytes();
const size_t continue_cstr_len = continue_packet->GetByteSize();
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got eBroadcastBitAsyncContinue: %s",
- __FUNCTION__, arg, process->GetID(), continue_cstr);
+ __FUNCTION__, GetID(), continue_cstr);
if (::strstr(continue_cstr, "vAttach") == nullptr)
- process->SetPrivateState(eStateRunning);
+ SetPrivateState(eStateRunning);
StringExtractorGDBRemote response;
StateType stop_state =
- process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
- *process, *process->GetUnixSignals(),
+ GetGDBRemote().SendContinuePacketAndWaitForResponse(
+ *this, *GetUnixSignals(),
llvm::StringRef(continue_cstr, continue_cstr_len),
- process->GetInterruptTimeout(), response);
+ GetInterruptTimeout(), response);
// We need to immediately clear the thread ID list so we are sure
// to get a valid list of threads. The thread ID list might be
// contained within the "response", or the stop reply packet that
// caused the stop. So clear it now before we give the stop reply
// packet to the process using the
- // process->SetLastStopPacket()...
- process->ClearThreadIDList();
+ // SetLastStopPacket()...
+ ClearThreadIDList();
switch (stop_state) {
case eStateStopped:
case eStateCrashed:
case eStateSuspended:
- process->SetLastStopPacket(response);
- process->SetPrivateState(stop_state);
+ SetLastStopPacket(response);
+ SetPrivateState(stop_state);
break;
case eStateExited: {
- process->SetLastStopPacket(response);
- process->ClearThreadIDList();
+ SetLastStopPacket(response);
+ ClearThreadIDList();
response.SetFilePos(1);
int exit_status = response.GetHexU8();
@@ -3675,7 +3583,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
extractor.GetHexByteString(desc_string);
}
}
- process->SetExitStatus(exit_status, desc_string.c_str());
+ SetExitStatus(exit_status, desc_string.c_str());
done = true;
break;
}
@@ -3686,20 +3594,20 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// helpful error message about why the attach failed.
if (::strstr(continue_cstr, "vAttach") != nullptr &&
response.GetError() == 0x87) {
- process->SetExitStatus(-1, "cannot attach to process due to "
- "System Integrity Protection");
+ SetExitStatus(-1, "cannot attach to process due to "
+ "System Integrity Protection");
} else if (::strstr(continue_cstr, "vAttach") != nullptr &&
response.GetStatus().Fail()) {
- process->SetExitStatus(-1, response.GetStatus().AsCString());
+ SetExitStatus(-1, response.GetStatus().AsCString());
} else {
- process->SetExitStatus(-1, "lost connection");
+ SetExitStatus(-1, "lost connection");
}
done = true;
break;
}
default:
- process->SetPrivateState(stop_state);
+ SetPrivateState(stop_state);
break;
} // switch(stop_state)
} // if (continue_packet)
@@ -3708,49 +3616,47 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
case eBroadcastBitAsyncThreadShouldExit:
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got eBroadcastBitAsyncThreadShouldExit...",
- __FUNCTION__, arg, process->GetID());
+ __FUNCTION__, GetID());
done = true;
break;
default:
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ __FUNCTION__, GetID(), event_type);
done = true;
break;
}
- } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) {
+ } else if (event_sp->BroadcasterIs(&m_gdb_comm)) {
switch (event_type) {
case Communication::eBroadcastBitReadThreadDidExit:
- process->SetExitStatus(-1, "lost connection");
+ SetExitStatus(-1, "lost connection");
done = true;
break;
default:
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ __FUNCTION__, GetID(), event_type);
done = true;
break;
}
}
} else {
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") listener.WaitForEvent (NULL, event_sp) => false",
- __FUNCTION__, arg, process->GetID());
+ __FUNCTION__, GetID());
done = true;
}
}
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread exiting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread exiting...",
+ __FUNCTION__, GetID());
return {};
}
@@ -3781,7 +3687,7 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
// I don't think I have to do anything here, just make sure I notice the new
// thread when it starts to
// run so I can stop it if that's what I want to do.
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ Log *log = GetLog(LLDBLog::Step);
LLDB_LOGF(log, "Hit New Thread Notification breakpoint.");
return false;
}
@@ -3824,7 +3730,7 @@ Status ProcessGDBRemote::UpdateAutomaticSignalFiltering() {
}
bool ProcessGDBRemote::StartNoticingNewThreads() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ Log *log = GetLog(LLDBLog::Step);
if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
LLDB_LOGF(log, "Enabled noticing new thread breakpoint.");
@@ -3850,7 +3756,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
}
bool ProcessGDBRemote::StopNoticingNewThreads() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ Log *log = GetLog(LLDBLog::Step);
if (log && log->GetVerbose())
LLDB_LOGF(log, "Disabling new thread notification breakpoint.");
@@ -4116,7 +4022,7 @@ void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize(
bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
const ArchSpec &arch,
ModuleSpec &module_spec) {
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ Log *log = GetLog(LLDBLog::Platform);
const ModuleCacheKey key(module_file_spec.GetPath(),
arch.GetTriple().getTriple());
@@ -4495,7 +4401,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"XML parsing not available");
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS);
+ Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "ProcessGDBRemote::%s", __FUNCTION__);
LoadedModuleInfoList list;
@@ -5102,19 +5008,12 @@ public:
~CommandObjectProcessGDBRemotePacketHistory() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0) {
- ProcessGDBRemote *process =
- (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
- .GetProcessPtr();
- if (process) {
- process->GetGDBRemote().DumpHistory(result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- } else {
- result.AppendErrorWithFormat("'%s' takes no arguments",
- m_cmd_name.c_str());
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ process->GetGDBRemote().DumpHistory(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
result.SetStatus(eReturnStatusFailed);
return false;
@@ -5128,7 +5027,10 @@ public:
: CommandObjectParsed(
interpreter, "process plugin packet xfer-size",
"Maximum size that lldb will try to read/write one one chunk.",
- nullptr) {}
+ nullptr) {
+ CommandArgumentData max_arg{eArgTypeUnsignedInteger, eArgRepeatPlain};
+ m_arguments.push_back({max_arg});
+ }
~CommandObjectProcessGDBRemotePacketXferSize() override = default;
@@ -5169,7 +5071,10 @@ public:
"The packet header and footer will automatically "
"be added to the packet prior to sending and "
"stripped from the result.",
- nullptr) {}
+ nullptr) {
+ CommandArgumentData packet_arg{eArgTypeNone, eArgRepeatStar};
+ m_arguments.push_back({packet_arg});
+ }
~CommandObjectProcessGDBRemotePacketSend() override = default;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index bdf130e3ec11..50cef8e499dc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -70,6 +70,8 @@ public:
static std::chrono::seconds GetPacketTimeout();
+ ArchSpec GetSystemArchitecture() override;
+
// Check if a given Process
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
@@ -143,9 +145,6 @@ public:
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
Status &error) override;
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) override;
-
Status DoDeallocateMemory(lldb::addr_t ptr) override;
// Process STDIO
@@ -284,7 +283,6 @@ protected:
MMapMap m_addr_to_mmap_size;
lldb::BreakpointSP m_thread_create_bp_sp;
bool m_waiting_for_attach;
- bool m_destroy_tried_resuming;
lldb::CommandObjectSP m_command_sp;
int64_t m_breakpoint_pc_offset;
lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
@@ -345,12 +343,11 @@ protected:
void StopAsyncThread();
- static lldb::thread_result_t AsyncThread(void *arg);
+ lldb::thread_result_t AsyncThread();
- static bool
+ static void
MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,
- lldb::pid_t pid, bool exited, int signo,
- int exit_status);
+ lldb::pid_t pid, int signo, int exit_status);
lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet);
@@ -415,6 +412,9 @@ protected:
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
const std::vector<uint8_t> &tags) override;
+ Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) override;
+
private:
// For ProcessGDBRemote only
std::string m_partial_profile_data;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index 730384204393..66b2f00f1ea9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -10,6 +10,7 @@
#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
#include "lldb/Utility/Log.h"
+#include "llvm/ADT/BitmaskEnum.h"
namespace lldb_private {
namespace process_gdb_remote {
@@ -28,6 +29,7 @@ enum class GDBRLog : Log::MaskType {
Watchpoints = Log::ChannelFlag<10>,
LLVM_MARK_AS_BITMASK_ENUM(Watchpoints)
};
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
class ProcessGDBRemoteLog {
public: