aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp267
1 files changed, 160 insertions, 107 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 1214812b60b0..b8a737586eb4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -8,8 +8,8 @@
#include "lldb/Host/Config.h"
-#include <errno.h>
-#include <stdlib.h>
+#include <cerrno>
+#include <cstdlib>
#if LLDB_ENABLE_POSIX
#include <netinet/in.h>
#include <sys/mman.h>
@@ -20,8 +20,8 @@
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
+#include <ctime>
#include <sys/types.h>
-#include <time.h>
#include <algorithm>
#include <csignal>
@@ -137,7 +137,7 @@ public:
m_collection_sp->Initialize(g_processgdbremote_properties);
}
- ~PluginProperties() override {}
+ ~PluginProperties() override = default;
uint64_t GetPacketTimeout() {
const uint32_t idx = ePropertyPacketTimeout;
@@ -215,6 +215,10 @@ ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
return process_sp;
}
+std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() {
+ return std::chrono::seconds(GetGlobalPluginProperties()->GetPacketTimeout());
+}
+
bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) {
if (plugin_specified_by_name)
@@ -463,7 +467,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
GDBRemoteCommunication::PacketResult::Success) {
response_type = response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse) {
@@ -1013,7 +1017,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
for (size_t idx = 0; idx < num_cmds; idx++) {
StringExtractorGDBRemote response;
m_gdb_comm.SendPacketAndWaitForResponse(
- GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
+ GetExtraStartupCommands().GetArgumentAtIndex(idx), response);
}
return error;
}
@@ -1040,6 +1044,12 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
process_arch.GetTriple().getTriple());
}
+ if (int addresssable_bits = m_gdb_comm.GetAddressingBits()) {
+ lldb::addr_t address_mask = ~((1ULL << addresssable_bits) - 1);
+ SetCodeAddressMask(address_mask);
+ SetDataAddressMask(address_mask);
+ }
+
if (process_arch.IsValid()) {
const ArchSpec &target_arch = GetTarget().GetArchitecture();
if (target_arch.IsValid()) {
@@ -1201,34 +1211,26 @@ Status ProcessGDBRemote::DoAttachToProcessWithName(
return error;
}
-lldb::user_id_t ProcessGDBRemote::StartTrace(const TraceOptions &options,
- Status &error) {
- return m_gdb_comm.SendStartTracePacket(options, error);
-}
-
-Status ProcessGDBRemote::StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) {
- return m_gdb_comm.SendStopTracePacket(uid, thread_id);
+llvm::Expected<TraceSupportedResponse> ProcessGDBRemote::TraceSupported() {
+ return m_gdb_comm.SendTraceSupported(GetInterruptTimeout());
}
-Status ProcessGDBRemote::GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- return m_gdb_comm.SendGetDataPacket(uid, thread_id, buffer, offset);
+llvm::Error ProcessGDBRemote::TraceStop(const TraceStopRequest &request) {
+ return m_gdb_comm.SendTraceStop(request, GetInterruptTimeout());
}
-Status ProcessGDBRemote::GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- return m_gdb_comm.SendGetMetaDataPacket(uid, thread_id, buffer, offset);
+llvm::Error ProcessGDBRemote::TraceStart(const llvm::json::Value &request) {
+ return m_gdb_comm.SendTraceStart(request, GetInterruptTimeout());
}
-Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid,
- TraceOptions &options) {
- return m_gdb_comm.SendGetTraceConfigPacket(uid, options);
+llvm::Expected<std::string>
+ProcessGDBRemote::TraceGetState(llvm::StringRef type) {
+ return m_gdb_comm.SendTraceGetState(type, GetInterruptTimeout());
}
-llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() {
- return m_gdb_comm.SendGetSupportedTraceType();
+llvm::Expected<std::vector<uint8_t>>
+ProcessGDBRemote::TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
+ return m_gdb_comm.SendTraceGetBinaryData(request, GetInterruptTimeout());
}
void ProcessGDBRemote::DidExit() {
@@ -1473,7 +1475,7 @@ void ProcessGDBRemote::HandleStopReplySequence() {
while (true) {
// Send vStopped
StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+ m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response);
// OK represents end of signal list
if (response.IsOKResponse())
@@ -1493,22 +1495,22 @@ void ProcessGDBRemote::ClearThreadIDList() {
m_thread_pcs.clear();
}
-size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
+size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(
+ llvm::StringRef value) {
m_thread_ids.clear();
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos) {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back(tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back(tid);
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ StringExtractorGDBRemote thread_ids{value};
+
+ do {
+ auto pid_tid = thread_ids.GetPidTid(pid);
+ if (pid_tid && pid_tid->first == pid) {
+ lldb::tid_t tid = pid_tid->second;
+ if (tid != LLDB_INVALID_THREAD_ID &&
+ tid != StringExtractorGDBRemote::AllProcesses)
+ m_thread_ids.push_back(tid);
+ }
+ } while (thread_ids.GetChar() == ',');
+
return m_thread_ids.size();
}
@@ -1525,7 +1527,7 @@ ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) {
value.erase(0, comma_pos + 1);
}
pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_THREAD_ID)
+ if (pc != LLDB_INVALID_ADDRESS)
m_thread_pcs.push_back(pc);
return m_thread_pcs.size();
}
@@ -1750,7 +1752,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (thread_sp) {
ThreadGDBRemote *gdb_thread =
static_cast<ThreadGDBRemote *>(thread_sp.get());
- gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+ RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext());
+
+ gdb_reg_ctx_sp->InvalidateIfNeeded(true);
auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid);
if (iter != m_thread_ids.end()) {
@@ -1762,7 +1766,10 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
DataBufferSP buffer_sp(new DataBufferHeap(
reg_value_extractor.GetStringRef().size() / 2, 0));
reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
- gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
+ uint32_t lldb_regnum =
+ gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindProcessPlugin, pair.first);
+ gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData());
}
// AArch64 SVE specific code below calls AArch64SVEReconfigure to update
@@ -1827,8 +1834,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// If the current pc is a breakpoint site then the StopInfo
// should be set to Breakpoint Otherwise, it will be set to
// Trace.
- if (bp_site_sp &&
- bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
*thread_sp, bp_site_sp->GetID()));
@@ -1848,7 +1854,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// breakpoint here, that will be taken care of when the thread
// resumes and notices that there's a breakpoint under the pc.
handled = true;
- if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp->ValidForThisThread(*thread_sp)) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
*thread_sp, bp_site_sp->GetID()));
@@ -1899,6 +1905,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithExec(*thread_sp));
handled = true;
+ } else if (reason == "processor trace") {
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonProcessorTrace(
+ *thread_sp, description.c_str()));
}
} else if (!signo) {
addr_t pc = thread_sp->GetRegisterContext()->GetPC();
@@ -1911,7 +1920,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// as such. This can happen when the thread is involuntarily
// interrupted (e.g. due to stops on other threads) just as it is
// about to execute the breakpoint instruction.
- if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
*thread_sp, bp_site_sp->GetID()));
@@ -1936,7 +1945,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// reason. We don't need to worry about stepping over the
// breakpoint here, that will be taken care of when the thread
// resumes and notices that there's a breakpoint under the pc.
- if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp->ValidForThisThread(*thread_sp)) {
if (m_breakpoint_pc_offset != 0)
thread_sp->GetRegisterContext()->SetPC(pc);
thread_sp->SetStopInfo(
@@ -2139,6 +2148,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
}
StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
stop_packet.SetFilePos(0);
const char stop_type = stop_packet.GetChar();
switch (stop_type) {
@@ -2153,14 +2163,12 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
if (stop_id == 0) {
// Our first stop, make sure we have a process ID, and also make sure we
// know about our registers
- if (GetID() == LLDB_INVALID_PROCESS_ID) {
- lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- SetID(pid);
- }
+ if (GetID() == LLDB_INVALID_PROCESS_ID && pid != LLDB_INVALID_PROCESS_ID)
+ SetID(pid);
BuildDynamicRegisterInfo(true);
}
// Stop with signal and thread info
+ lldb::pid_t stop_pid = LLDB_INVALID_PROCESS_ID;
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
const uint8_t signo = stop_packet.GetHexU8();
llvm::StringRef key;
@@ -2189,24 +2197,18 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
value.getAsInteger(16, x);
exc_data.push_back(x);
} else if (key.compare("thread") == 0) {
- // thread in big endian hex
- if (value.getAsInteger(16, tid))
+ // thread-id
+ StringExtractorGDBRemote thread_id{value};
+ auto pid_tid = thread_id.GetPidTid(pid);
+ if (pid_tid) {
+ stop_pid = pid_tid->first;
+ tid = pid_tid->second;
+ } else
tid = LLDB_INVALID_THREAD_ID;
} else if (key.compare("threads") == 0) {
std::lock_guard<std::recursive_mutex> guard(
m_thread_list_real.GetMutex());
-
- m_thread_ids.clear();
- // A comma separated list of all threads in the current
- // process that includes the thread for this stop reply packet
- lldb::tid_t tid;
- while (!value.empty()) {
- llvm::StringRef tid_str;
- std::tie(tid_str, value) = value.split(',');
- if (tid_str.getAsInteger(16, tid))
- tid = LLDB_INVALID_THREAD_ID;
- m_thread_ids.push_back(tid);
- }
+ UpdateThreadIDsFromStopReplyThreadsValue(value);
} else if (key.compare("thread-pcs") == 0) {
m_thread_pcs.clear();
// A comma separated list of all threads in the current
@@ -2319,6 +2321,14 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
}
}
+ if (stop_pid != LLDB_INVALID_PROCESS_ID && stop_pid != pid) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOG(log,
+ "Received stop for incorrect PID = {0} (inferior PID = {1})",
+ stop_pid, pid);
+ return eStateInvalid;
+ }
+
if (tid == LLDB_INVALID_THREAD_ID) {
// A thread id may be invalid if the response is old style 'S' packet
// which does not provide the
@@ -2406,7 +2416,7 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) {
// file handle and debugserver will go away, and we can be done...
m_gdb_comm.Disconnect();
} else
- caused_stop = m_gdb_comm.Interrupt();
+ caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());
return error;
}
@@ -2557,11 +2567,11 @@ Status ProcessGDBRemote::DoDestroy() {
if (m_gdb_comm.IsConnected()) {
if (m_public_state.GetValue() != eStateAttaching) {
StringExtractorGDBRemote response;
- bool send_async = true;
GDBRemoteCommunication::ScopedTimeout(m_gdb_comm,
std::chrono::seconds(3));
- if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, send_async) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse("k", response,
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
char packet_cmd = response.GetChar(0);
@@ -2725,7 +2735,8 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
assert(packet_len + 1 < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, true) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsNormalResponse()) {
error.Clear();
@@ -2761,6 +2772,37 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
return 0;
}
+bool ProcessGDBRemote::SupportsMemoryTagging() {
+ return m_gdb_comm.GetMemoryTaggingSupported();
+}
+
+llvm::Expected<std::vector<uint8_t>>
+ProcessGDBRemote::DoReadMemoryTags(lldb::addr_t addr, size_t len,
+ int32_t type) {
+ // By this point ReadMemoryTags has validated that tagging is enabled
+ // for this target/process/address.
+ DataBufferSP buffer_sp = m_gdb_comm.ReadMemoryTags(addr, len, type);
+ if (!buffer_sp) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error reading memory tags from remote");
+ }
+
+ // Return the raw tag data
+ llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
+ std::vector<uint8_t> got;
+ got.reserve(tag_data.size());
+ std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
+ return got;
+}
+
+Status ProcessGDBRemote::DoWriteMemoryTags(lldb::addr_t addr, size_t len,
+ int32_t type,
+ const std::vector<uint8_t> &tags) {
+ // By now WriteMemoryTags should have validated that tagging is enabled
+ // for this target/process.
+ return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
+}
+
Status ProcessGDBRemote::WriteObjectFile(
std::vector<ObjectFile::LoadableData> entries) {
Status error;
@@ -2851,7 +2893,7 @@ Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) {
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- true) ==
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsOKResponse()) {
m_erased_flash_ranges.Insert(range, true);
@@ -2880,7 +2922,8 @@ Status ProcessGDBRemote::FlashDone() {
if (m_erased_flash_ranges.IsEmpty())
return status;
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, true) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response,
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsOKResponse()) {
m_erased_flash_ranges.Clear();
@@ -2941,7 +2984,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
}
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- true) ==
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsOKResponse()) {
error.Clear();
@@ -3117,7 +3160,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
(!bp_site->HardwareRequired())) {
// Try to send off a software breakpoint packet ($Z0)
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
- eBreakpointSoftware, true, addr, bp_op_size);
+ eBreakpointSoftware, true, addr, bp_op_size, GetInterruptTimeout());
if (error_no == 0) {
// The breakpoint was placed successfully
bp_site->SetEnabled(true);
@@ -3157,7 +3200,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
// Try to send off a hardware breakpoint packet ($Z1)
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
- eBreakpointHardware, true, addr, bp_op_size);
+ eBreakpointHardware, true, addr, bp_op_size, GetInterruptTimeout());
if (error_no == 0) {
// The breakpoint was placed successfully
bp_site->SetEnabled(true);
@@ -3221,13 +3264,15 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
case BreakpointSite::eHardware:
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,
- addr, bp_op_size))
+ addr, bp_op_size,
+ GetInterruptTimeout()))
error.SetErrorToGenericError();
break;
case BreakpointSite::eExternal: {
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false,
- addr, bp_op_size))
+ addr, bp_op_size,
+ GetInterruptTimeout()))
error.SetErrorToGenericError();
} break;
}
@@ -3283,7 +3328,8 @@ Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
// Pass down an appropriate z/Z packet...
if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
- wp->GetByteSize()) == 0) {
+ wp->GetByteSize(),
+ GetInterruptTimeout()) == 0) {
wp->SetEnabled(true, notify);
return error;
} else
@@ -3329,7 +3375,8 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
GDBStoppointType type = GetGDBStoppointType(wp);
// Pass down an appropriate z/Z packet...
if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
- wp->GetByteSize()) == 0) {
+ wp->GetByteSize(),
+ GetInterruptTimeout()) == 0) {
wp->SetEnabled(false, notify);
return error;
} else
@@ -3354,7 +3401,7 @@ Status ProcessGDBRemote::DoSignal(int signo) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo);
- if (!m_gdb_comm.SendAsyncSignal(signo))
+ if (!m_gdb_comm.SendAsyncSignal(signo, GetInterruptTimeout()))
error.SetErrorStringWithFormat("failed to send signal %i", signo);
return error;
}
@@ -3682,12 +3729,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
__FUNCTION__, arg, process->GetID());
EventSP event_sp;
+
+ // We need to ignore any packets that come in after we have
+ // have decided the process has exited. There are some
+ // situations, for instance when we try to interrupt a running
+ // process and the interrupt fails, where another packet might
+ // get delivered after we've decided to give up on the process.
+ // But once we've decided we are done with the process we will
+ // not be in a state to do anything useful with new packets.
+ // So it is safer to simply ignore any remaining packets by
+ // explicitly checking for eStateExited before reentering the
+ // fetch loop.
+
bool done = false;
- while (!done) {
+ while (!done && process->GetPrivateState() != eStateExited) {
LLDB_LOGF(log,
"ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
") listener.WaitForEvent (NULL, event_sp)...",
__FUNCTION__, arg, process->GetID());
+
if (process->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)) {
@@ -3719,7 +3779,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// send the vCont packet
if (!process->GetGDBRemote().SendvContPacket(
llvm::StringRef(continue_cstr, continue_cstr_len),
- response)) {
+ process->GetInterruptTimeout(), response)) {
// Something went wrong
done = true;
break;
@@ -3731,6 +3791,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
*process, *process->GetUnixSignals(),
llvm::StringRef(continue_cstr, continue_cstr_len),
+ process->GetInterruptTimeout(),
response);
// We need to immediately clear the thread ID list so we are sure
@@ -3786,6 +3847,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
} else {
process->SetExitStatus(-1, "lost connection");
}
+ done = true;
break;
}
@@ -4024,8 +4086,7 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success) {
StringExtractorGDBRemote::ResponseType response_type =
response.GetResponseType();
@@ -4097,8 +4158,7 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success) {
StringExtractorGDBRemote::ResponseType response_type =
response.GetResponseType();
@@ -4131,8 +4191,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success) {
StringExtractorGDBRemote::ResponseType response_type =
response.GetResponseType();
@@ -4898,8 +4957,7 @@ Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
packet.PutStringAsRawHex8(file_path);
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) !=
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
GDBRemoteCommunication::PacketResult::Success)
return Status("Sending qFileLoadAddress packet failed");
@@ -5135,7 +5193,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectProcessGDBRemoteSpeedTest() override {}
+ ~CommandObjectProcessGDBRemoteSpeedTest() override = default;
Options *GetOptions() override { return &m_option_group; }
@@ -5186,7 +5244,7 @@ public:
: CommandObjectParsed(interpreter, "process plugin packet history",
"Dumps the packet history buffer. ", nullptr) {}
- ~CommandObjectProcessGDBRemotePacketHistory() override {}
+ ~CommandObjectProcessGDBRemotePacketHistory() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5217,7 +5275,7 @@ public:
"Maximum size that lldb will try to read/write one one chunk.",
nullptr) {}
- ~CommandObjectProcessGDBRemotePacketXferSize() override {}
+ ~CommandObjectProcessGDBRemotePacketXferSize() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5226,7 +5284,6 @@ public:
"amount to be transferred when "
"reading/writing",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -5259,7 +5316,7 @@ public:
"stripped from the result.",
nullptr) {}
- ~CommandObjectProcessGDBRemotePacketSend() override {}
+ ~CommandObjectProcessGDBRemotePacketSend() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5267,7 +5324,6 @@ public:
result.AppendErrorWithFormat(
"'%s' takes a one or more packet content arguments",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -5276,10 +5332,9 @@ public:
if (process) {
for (size_t i = 0; i < argc; ++i) {
const char *packet_cstr = command.GetArgumentAtIndex(0);
- bool send_async = true;
StringExtractorGDBRemote response;
process->GetGDBRemote().SendPacketAndWaitForResponse(
- packet_cstr, response, send_async);
+ packet_cstr, response, process->GetInterruptTimeout());
result.SetStatus(eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
output_strm.Printf(" packet: %s\n", packet_cstr);
@@ -5310,14 +5365,13 @@ public:
"encoded into a valid 'qRcmd' packet, sent and the "
"response will be printed.") {}
- ~CommandObjectProcessGDBRemotePacketMonitor() override {}
+ ~CommandObjectProcessGDBRemotePacketMonitor() override = default;
bool DoExecute(llvm::StringRef command,
CommandReturnObject &result) override {
if (command.empty()) {
result.AppendErrorWithFormat("'%s' takes a command string argument",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -5328,11 +5382,10 @@ public:
packet.PutCString("qRcmd,");
packet.PutBytesAsRawHex8(command.data(), command.size());
- bool send_async = true;
StringExtractorGDBRemote response;
Stream &output_strm = result.GetOutputStream();
process->GetGDBRemote().SendPacketAndReceiveResponseWithOutputSupport(
- packet.GetString(), response, send_async,
+ packet.GetString(), response, process->GetInterruptTimeout(),
[&output_strm](llvm::StringRef output) { output_strm << output; });
result.SetStatus(eReturnStatusSuccessFinishResult);
output_strm.Printf(" packet: %s\n", packet.GetData());
@@ -5374,7 +5427,7 @@ public:
interpreter)));
}
- ~CommandObjectProcessGDBRemotePacket() override {}
+ ~CommandObjectProcessGDBRemotePacket() override = default;
};
class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
@@ -5389,7 +5442,7 @@ public:
CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
}
- ~CommandObjectMultiwordProcessGDBRemote() override {}
+ ~CommandObjectMultiwordProcessGDBRemote() override = default;
};
CommandObject *ProcessGDBRemote::GetPluginCommandObject() {