diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /lldb/source/Plugins/Process | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'lldb/source/Plugins/Process')
82 files changed, 1089 insertions, 679 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp index 21c9ead0eca4..5d73ec3457e3 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp @@ -497,6 +497,10 @@ Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) { Status NativeProcessFreeBSD::Halt() { Status error; + // Do not try to stop a process that's already stopped, this may cause + // the SIGSTOP to get queued and stop the process again once resumed. + if (StateIsStoppedState(m_state, false)) + return error; if (kill(GetID(), SIGSTOP) != 0) error.SetErrorToErrno(); return error; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp index c4ee3773eaeb..2c5017664387 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp @@ -140,7 +140,7 @@ Status NativeRegisterContextFreeBSD_arm::WriteRegister( } Status NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet); @@ -177,7 +177,7 @@ Status NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm::%s " "DataBuffer::GetBytes() returned a null " diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h index 4be75b958fc1..89ffa617294a 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h @@ -44,7 +44,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index 143d94069bc6..9db5970af653 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -149,7 +149,7 @@ Status NativeRegisterContextFreeBSD_arm64::WriteRegister( } Status NativeRegisterContextFreeBSD_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(RegisterInfoPOSIX_arm64::GPRegSet); @@ -186,7 +186,7 @@ Status NativeRegisterContextFreeBSD_arm64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h index a230f8fed48a..799209e26e86 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h @@ -51,7 +51,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp index d93b7fd33815..83664b586960 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp @@ -176,7 +176,7 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister( } Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(GPRegSet); @@ -213,7 +213,7 @@ Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h index 8e300ed829c9..7a2c0b34eeee 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h @@ -44,7 +44,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp index 5b5d44a308b1..ee125e5e6881 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp @@ -227,7 +227,7 @@ Status NativeRegisterContextFreeBSD_powerpc::WriteRegister( } Status NativeRegisterContextFreeBSD_powerpc::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(GPRegSet); @@ -264,7 +264,7 @@ Status NativeRegisterContextFreeBSD_powerpc::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_powerpc::%s " "DataBuffer::GetBytes() returned a null " diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h index 884c25988ce1..c77394366517 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h @@ -44,7 +44,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp index 9328d606ad26..b69cfa7d5d83 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp @@ -537,7 +537,7 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteRegister( } Status NativeRegisterContextFreeBSD_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); @@ -571,7 +571,7 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_x86_64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h index efd0f91f77b9..366a89b6eec8 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h @@ -48,7 +48,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp index a75668f3b5c7..8e6399bcf9c7 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp @@ -81,7 +81,7 @@ void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo, SetStopped(); m_stop_info.reason = StopReason::eStopReasonSignal; - m_stop_info.details.signal.signo = signo; + m_stop_info.signo = signo; m_stop_description.clear(); if (info) { @@ -100,19 +100,19 @@ void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo, void NativeThreadFreeBSD::SetStoppedByBreakpoint() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonBreakpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByTrace() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonTrace; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByExec() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonExec; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) { @@ -127,7 +127,7 @@ void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) { SetStopped(); m_stop_description = ostr.str(); m_stop_info.reason = StopReason::eStopReasonWatchpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid, @@ -135,6 +135,7 @@ void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -144,6 +145,7 @@ void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonVFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -152,13 +154,14 @@ void NativeThreadFreeBSD::SetStoppedByVForkDone() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonVForkDone; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedWithNoReason() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonNone; - m_stop_info.details.signal.signo = 0; + m_stop_info.signo = 0; } void NativeThreadFreeBSD::SetStopped() { diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index 3d164eadbea7..5a910b5a6ec9 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -527,7 +527,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( } Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); @@ -561,7 +561,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h index 31005952dd75..795cbeefd467 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h +++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -46,7 +46,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp index 3e8cf9fd9f23..995fe3fa78e8 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -81,7 +81,7 @@ void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo, SetStopped(); m_stop_info.reason = StopReason::eStopReasonSignal; - m_stop_info.details.signal.signo = signo; + m_stop_info.signo = signo; m_stop_description.clear(); if (info) { @@ -100,19 +100,19 @@ void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo, void NativeThreadNetBSD::SetStoppedByBreakpoint() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonBreakpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByTrace() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonTrace; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByExec() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonExec; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) { @@ -127,7 +127,7 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) { SetStopped(); m_stop_description = ostr.str(); m_stop_info.reason = StopReason::eStopReasonWatchpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid, @@ -135,6 +135,7 @@ void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -144,6 +145,7 @@ void NativeThreadNetBSD::SetStoppedByVFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonVFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -152,13 +154,14 @@ void NativeThreadNetBSD::SetStoppedByVForkDone() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonVForkDone; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedWithNoReason() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonNone; - m_stop_info.details.signal.signo = 0; + m_stop_info.signo = 0; } void NativeThreadNetBSD::SetStopped() { diff --git a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp index 117d12101a0b..cbaa1fc7a2b1 100644 --- a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp +++ b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp @@ -28,7 +28,7 @@ NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) { } lldb::addr_t NativeProcessELF::GetSharedLibraryInfoAddress() { - if (!m_shared_library_info_addr.hasValue()) { + if (!m_shared_library_info_addr) { if (GetAddressByteSize() == 8) m_shared_library_info_addr = GetELFImageInfoAddress<llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr, @@ -39,7 +39,7 @@ lldb::addr_t NativeProcessELF::GetSharedLibraryInfoAddress() { llvm::ELF::Elf32_Dyn>(); } - return m_shared_library_info_addr.getValue(); + return *m_shared_library_info_addr; } template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN> @@ -180,4 +180,9 @@ NativeProcessELF::GetLoadedSVR4Libraries() { return library_list; } +void NativeProcessELF::NotifyDidExec() { + NativeProcessProtocol::NotifyDidExec(); + m_shared_library_info_addr.reset(); +} + } // namespace lldb_private diff --git a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h index c01409940daa..8e92899defec 100644 --- a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h +++ b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h @@ -45,6 +45,8 @@ protected: llvm::Expected<SVR4LibraryInfo> ReadSVR4LibraryInfo(lldb::addr_t link_map_addr); + void NotifyDidExec() override; + std::unique_ptr<AuxVector> m_aux_vector; llvm::Optional<lldb::addr_t> m_shared_library_info_addr; }; diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h index 7b8b6cdbf255..88cfdfd204c0 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h @@ -10,8 +10,8 @@ #ifndef liblldb_ProcessPOSIXLog_h_ #define liblldb_ProcessPOSIXLog_h_ - #include "lldb/Utility/Log.h" +#include "llvm/ADT/BitmaskEnum.h" namespace lldb_private { @@ -23,8 +23,10 @@ enum class POSIXLog : Log::MaskType { Registers = Log::ChannelFlag<4>, Thread = Log::ChannelFlag<5>, Watchpoints = Log::ChannelFlag<6>, - LLVM_MARK_AS_BITMASK_ENUM(Watchpoints) + Trace = Log::ChannelFlag<7>, + LLVM_MARK_AS_BITMASK_ENUM(Trace) }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); class ProcessPOSIXLog { public: diff --git a/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/lldb/source/Plugins/Process/Utility/HistoryThread.cpp index d73b132539f1..bc06757c806a 100644 --- a/lldb/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -15,6 +15,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/StackFrameList.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include <memory> @@ -33,14 +34,14 @@ HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, m_queue_id(LLDB_INVALID_QUEUE_ID) { m_unwinder_up = std::make_unique<HistoryUnwind>(*this, pcs, pcs_are_call_addresses); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this)); } // Destructor HistoryThread::~HistoryThread() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")", static_cast<void *>(this), GetID()); DestroyThread(); diff --git a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp index 947b970edf6c..2a15f9813749 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -94,7 +94,15 @@ ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line, return ProcMapError("unexpected /proc/{pid}/%s exec permission char", maps_kind); - line_extractor.GetChar(); // Read the private bit + // Handle sharing status (private/shared). + const char sharing_char = line_extractor.GetChar(); + if (sharing_char == 's') + region.SetShared(MemoryRegionInfo::OptionalBool::eYes); + else if (sharing_char == 'p') + region.SetShared(MemoryRegionInfo::OptionalBool::eNo); + else + region.SetShared(MemoryRegionInfo::OptionalBool::eDontKnow); + line_extractor.SkipSpaces(); // Skip the separator line_extractor.GetHexMaxU64(false, 0); // Read the offset line_extractor.GetHexMaxU64(false, 0); // Read the major device number diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp index feee857cfe5f..4bec3de58668 100644 --- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp @@ -8,6 +8,7 @@ #include "NativeRegisterContextDBReg_arm64.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" @@ -29,7 +30,7 @@ static constexpr inline uint64_t GetSizeBits(int size) { } uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); llvm::Error error = ReadHardwareDebugInfo(); if (error) { LLDB_LOG_ERROR(log, std::move(error), @@ -43,7 +44,7 @@ uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() { uint32_t NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size); // Read hardware breakpoint and watchpoint information. @@ -104,7 +105,7 @@ NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr, bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint( uint32_t hw_idx) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "hw_idx: {0}", hw_idx); // Read hardware breakpoint and watchpoint information. @@ -144,7 +145,7 @@ bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint( Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex( uint32_t &bp_index, lldb::addr_t trap_addr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__); @@ -164,7 +165,7 @@ Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex( } Status NativeRegisterContextDBReg_arm64::ClearAllHardwareBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__); @@ -206,7 +207,7 @@ bool NativeRegisterContextDBReg_arm64::BreakpointIsEnabled(uint32_t bp_index) { } uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); llvm::Error error = ReadHardwareDebugInfo(); if (error) { LLDB_LOG_ERROR(log, std::move(error), @@ -219,7 +220,7 @@ uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() { uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint( lldb::addr_t addr, size_t size, uint32_t watch_flags) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size, watch_flags); @@ -312,7 +313,7 @@ uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint( bool NativeRegisterContextDBReg_arm64::ClearHardwareWatchpoint( uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); // Read hardware breakpoint and watchpoint information. @@ -384,7 +385,7 @@ Status NativeRegisterContextDBReg_arm64::ClearAllHardwareWatchpoints() { uint32_t NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) { @@ -402,7 +403,7 @@ NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) { } bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); if ((m_hwp_regs[wp_index].control & g_enable_bit) != 0) @@ -413,7 +414,7 @@ bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) { Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex( uint32_t &wp_index, lldb::addr_t trap_addr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr); // Read hardware breakpoint and watchpoint information. @@ -444,7 +445,7 @@ Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex( lldb::addr_t NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); if (wp_index >= m_max_hwp_supported) @@ -457,7 +458,7 @@ NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) { lldb::addr_t NativeRegisterContextDBReg_arm64::GetWatchpointHitAddress(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); if (wp_index >= m_max_hwp_supported) diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp index 56c1757ee89d..222e4a2690e4 100644 --- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp +++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp @@ -7,8 +7,7 @@ //===----------------------------------------------------------------------===// #include "NativeRegisterContextDBReg_x86.h" - -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" @@ -242,7 +241,7 @@ Status NativeRegisterContextDBReg_x86::ClearAllHardwareWatchpoints() { uint32_t NativeRegisterContextDBReg_x86::SetHardwareWatchpoint( lldb::addr_t addr, size_t size, uint32_t watch_flags) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) { bool is_vacant; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index e1d3b6ecd7d0..33bab249d960 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -1236,7 +1236,7 @@ bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_arm::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (data_sp && ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) { diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h index 1bd60f756487..7ff1bded81f4 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -66,7 +66,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/Utility/RegisterContextDarwin_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 50f710e26815..11b300bc44fb 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -643,7 +643,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) { diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index 010e566be32c..a0d7821ae9e8 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -48,7 +48,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/Utility/RegisterContextDarwin_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 5f56e6f1636a..9158f8acc2e7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -793,7 +793,7 @@ bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_i386::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { uint8_t *dst = data_sp->GetBytes(); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h index 9c759c31caed..be933f3be266 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -35,7 +35,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/Utility/RegisterContextDarwin_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 567df8fc980c..ad25ebbbb804 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -852,7 +852,7 @@ bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { uint8_t *dst = data_sp->GetBytes(); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h index d9ba8d0b2319..a132f92d4d49 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -35,7 +35,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/Utility/RegisterContextDummy.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp index 4c2e291c62d6..f41aa2ca599e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -102,7 +102,8 @@ bool RegisterContextDummy::WriteRegister( return false; } -bool RegisterContextDummy::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) { +bool RegisterContextDummy::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h index de98767693fe..631ad30b16a8 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -43,7 +43,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/Utility/RegisterContextHistory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp index 577958738900..f06af93cfa83 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -104,7 +104,7 @@ bool RegisterContextHistory::WriteRegister( } bool RegisterContextHistory::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h index 407640d2bdb9..a1eadac5d1b7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -43,7 +43,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/Utility/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h index 1ceca65c97c3..fedd0062c99c 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -16,7 +16,7 @@ public: RegisterContextMach_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - virtual ~RegisterContextMach_arm(); + ~RegisterContextMach_arm() override; protected: int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h index da5411eb2de2..8bdac083863d 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -16,7 +16,7 @@ public: RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - virtual ~RegisterContextMach_i386(); + ~RegisterContextMach_i386() override; protected: int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h index c131c8282bd2..99841a8e9a8d 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -17,7 +17,7 @@ public: RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - virtual ~RegisterContextMach_x86_64(); + ~RegisterContextMach_x86_64() override; protected: int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 49a4c8669022..ead8c4b4a80d 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -32,9 +32,9 @@ RegisterContextMemory::RegisterContextMemory(Thread &thread, m_reg_valid.resize(num_regs); // Make a heap based buffer that is big enough to store all registers - DataBufferSP reg_data_sp( - new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0)); - m_reg_data.SetData(reg_data_sp); + m_data = + std::make_shared<DataBufferHeap>(reg_infos.GetRegisterDataByteSize(), 0); + m_reg_data.SetData(m_data); } // Destructor @@ -76,7 +76,7 @@ bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) { const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; if (!m_reg_valid[reg_num]) { - if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer())) + if (!ReadAllRegisterValues(m_data)) return false; } const bool partial_data_ok = false; @@ -99,7 +99,8 @@ bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info, return false; } -bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) { +bool RegisterContextMemory::ReadAllRegisterValues( + WritableDataBufferSP &data_sp) { if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { ProcessSP process_sp(CalculateProcess()); if (process_sp) { diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index c3b9ec72ca22..2aad99ec9b21 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -50,7 +50,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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; @@ -61,6 +61,7 @@ protected: lldb_private::DynamicRegisterInfo &m_reg_infos; std::vector<bool> m_reg_valid; + lldb::WritableDataBufferSP m_data; lldb_private::DataExtractor m_reg_data; lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register // context that is stored in memmory diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp index 4866cbd235e8..b5f2b0d2212d 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -107,7 +107,7 @@ bool RegisterContextThreadMemory::WriteRegister( } bool RegisterContextThreadMemory::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { UpdateRegisterContext(); if (m_reg_ctx_sp) return m_reg_ctx_sp->ReadAllRegisterValues(data_sp); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h index 40688a502a66..0a7314528f0a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -51,7 +51,7 @@ public: // is a somewhat disruptive operation, // so these API's should only be used when this behavior is needed. - 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/Utility/RegisterInfoPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp index d6c4a8687ec5..579ac6e36d0b 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -72,6 +72,12 @@ #include "RegisterInfos_arm64_sve.h" #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT +static lldb_private::RegisterInfo g_register_infos_pauth[] = { + DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)}; + +static lldb_private::RegisterInfo g_register_infos_mte[] = { + DEFINE_EXTENSION_REG(mte_ctrl)}; + // Number of register sets provided by this context. enum { k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h index ccfbd6afbefb..d647fcaa600a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -784,10 +784,5 @@ static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { {DEFINE_DBG(wcr, 15)} }; // clang-format on -static lldb_private::RegisterInfo g_register_infos_pauth[] = { - DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)}; - -static lldb_private::RegisterInfo g_register_infos_mte[] = { - DEFINE_EXTENSION_REG(mte_ctrl)}; #endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 65dbc8ea95b3..58b4fe3add1b 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -15,11 +15,13 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -280,13 +282,16 @@ bool ProcessElfCore::IsAlive() { return true; } // Process Memory size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) { + if (lldb::ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddress(addr); + // Don't allow the caching that lldb_private::Process::ReadMemory does since // in core files we have it all cached our our core file anyway. return DoReadMemory(addr, buf, size, error); } -Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion_info) { +Status ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion_info) { region_info.Clear(); const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr); @@ -402,7 +407,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data, lldb::offset_t offset = 0; int pr_version = data.GetU32(&offset); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { if (pr_version > 1) LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version); @@ -430,7 +435,7 @@ static void ParseFreeBSDPrPsInfo(ProcessElfCore &process, lldb::offset_t offset = 0; int pr_version = data.GetU32(&offset); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { if (pr_version > 1) LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version); diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 67df3c5fac76..fd36e5027816 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -86,10 +86,6 @@ public: size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Status &error) override; - lldb_private::Status - GetMemoryRegionInfo(lldb::addr_t load_addr, - lldb_private::MemoryRegionInfo ®ion_info) override; - lldb::addr_t GetImageInfoAddress() override; lldb_private::ArchSpec GetArchitecture(); @@ -105,6 +101,10 @@ protected: bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override; + lldb_private::Status + DoGetMemoryRegionInfo(lldb::addr_t load_addr, + lldb_private::MemoryRegionInfo ®ion_info) override; + private: struct NT_FILE_Entry { lldb::addr_t start; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index f0aee04b5f62..3a62081827c6 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -55,7 +55,7 @@ bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_arm::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h index de343f9001e0..8d773a046bca 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h @@ -30,7 +30,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index e56aa88b57d9..bb88ce9e9e50 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -230,7 +230,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index 3988e3539b89..f8548562adba 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -31,7 +31,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/elf-core/RegisterContextPOSIXCore_mips64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 5b1eb8b5437d..56e68742ead7 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -72,7 +72,7 @@ bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_mips64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index b42a76c082f0..529b00215e35 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -30,7 +30,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index 8380731692a3..4e7be91c3895 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -92,7 +92,7 @@ bool RegisterContextCorePOSIX_powerpc::ReadRegister( } bool RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h index cf50b6e0bf70..5364c5589238 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h @@ -29,7 +29,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/elf-core/RegisterContextPOSIXCore_s390x.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index f1cd6897616d..69707eeb3f1e 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -77,7 +77,7 @@ bool RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_s390x::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h index 4560f062e06f..edb7cbc9462f 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h @@ -29,7 +29,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 6eaad9f381d6..6bc8edb9226f 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -80,7 +80,7 @@ bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h index 9adfbf7e6852..46416a2381db 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h @@ -26,7 +26,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::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/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 937d074869a2..bb190104cf2f 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -11,6 +11,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" @@ -64,7 +65,7 @@ RegisterContextSP ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); 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 ®_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 ®_ctx = thread.GetRegisterContext(); const auto expedited_regs = reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); @@ -922,8 +933,9 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( ®_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 ®_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 ®ion_info) { +Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr, + MemoryRegionInfo ®ion_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 ®ion_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 ®ion_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: diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index 61106ebcc430..ecf363aa2e73 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -12,6 +12,7 @@ #include "Plugins/Process/Utility/LinuxProcMaps.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" // C includes @@ -44,8 +45,7 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetData() { } llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) { - return m_file->getRawStream(stream_type) - .getValueOr(llvm::ArrayRef<uint8_t>()); + return m_file->getRawStream(stream_type).value_or(llvm::ArrayRef<uint8_t>()); } UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) { @@ -84,8 +84,7 @@ llvm::ArrayRef<minidump::Thread> MinidumpParser::GetThreads() { if (ExpectedThreads) return *ExpectedThreads; - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD), - ExpectedThreads.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), ExpectedThreads.takeError(), "Failed to read thread list: {0}"); return {}; } @@ -141,8 +140,7 @@ ArchSpec MinidumpParser::GetArchitecture() { llvm::Expected<const SystemInfo &> system_info = m_file->getSystemInfo(); if (!system_info) { - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), - system_info.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Process), system_info.takeError(), "Failed to read SystemInfo stream: {0}"); return m_arch; } @@ -200,8 +198,7 @@ ArchSpec MinidumpParser::GetArchitecture() { triple.setOS(llvm::Triple::OSType::UnknownOS); auto ExpectedCSD = m_file->getString(system_info->CSDVersionRVA); if (!ExpectedCSD) { - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), - ExpectedCSD.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedCSD.takeError(), "Failed to CSD Version string: {0}"); } else { if (ExpectedCSD->find("Linux") != std::string::npos) @@ -239,7 +236,7 @@ llvm::Optional<lldb::pid_t> MinidumpParser::GetPid() { } llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus(); - if (proc_status.hasValue()) { + if (proc_status) { return proc_status->GetPid(); } @@ -251,8 +248,7 @@ llvm::ArrayRef<minidump::Module> MinidumpParser::GetModuleList() { if (ExpectedModules) return *ExpectedModules; - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES), - ExpectedModules.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Modules), ExpectedModules.takeError(), "Failed to read module list: {0}"); return {}; } @@ -264,7 +260,7 @@ CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, if (data.empty()) return false; - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); ParseLinuxMapRegions( llvm::toStringRef(data), [®ions, &log](llvm::Expected<MemoryRegionInfo> region) -> bool { @@ -345,7 +341,7 @@ static bool CheckForLinuxExecutable(ConstString path, } std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedModules = GetMinidumpFile().getModuleList(); if (!ExpectedModules) { LLDB_LOG_ERROR(log, ExpectedModules.takeError(), @@ -425,8 +421,7 @@ const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { if (ExpectedStream) return &*ExpectedStream; - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), - ExpectedStream.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedStream.takeError(), "Failed to read minidump exception stream: {0}"); return nullptr; } @@ -434,7 +429,7 @@ const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { llvm::Optional<minidump::Range> MinidumpParser::FindMemoryRange(lldb::addr_t addr) { llvm::ArrayRef<uint8_t> data64 = GetStream(StreamType::Memory64List); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedMemory = GetMinidumpFile().getMemoryList(); if (!ExpectedMemory) { @@ -519,7 +514,7 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr, static bool CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, std::vector<MemoryRegionInfo> ®ions) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedInfo = parser.GetMinidumpFile().getMemoryInfoList(); if (!ExpectedInfo) { LLDB_LOG_ERROR(log, ExpectedInfo.takeError(), @@ -556,7 +551,7 @@ CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, static bool CreateRegionsCacheFromMemoryList(MinidumpParser &parser, std::vector<MemoryRegionInfo> ®ions) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedMemory = parser.GetMinidumpFile().getMemoryList(); if (!ExpectedMemory) { LLDB_LOG_ERROR(log, ExpectedMemory.takeError(), diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 37ee5466c5b9..c91c111d8df3 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -27,6 +27,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "llvm/BinaryFormat/Magic.h" @@ -291,12 +292,12 @@ Status ProcessMinidump::DoLoadCore() { llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid(); if (!pid) { - GetTarget().GetDebugger().GetAsyncErrorStream()->PutCString( - "Unable to retrieve process ID from minidump file, setting process ID " - "to 1.\n"); + Debugger::ReportWarning("unable to retrieve process ID from minidump file, " + "setting process ID to 1", + GetTarget().GetDebugger().GetID()); pid = 1; } - SetID(pid.getValue()); + SetID(*pid); return error; } @@ -439,8 +440,8 @@ void ProcessMinidump::BuildMemoryRegions() { llvm::sort(*m_memory_regions); } -Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion) { +Status ProcessMinidump::DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion) { BuildMemoryRegions(); region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr); return Status(); @@ -480,7 +481,7 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list, ModuleSP ProcessMinidump::GetOrCreateModule(UUID minidump_uuid, llvm::StringRef name, ModuleSpec module_spec) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); Status error; ModuleSP module_sp = @@ -528,7 +529,7 @@ void ProcessMinidump::ReadModuleList() { std::vector<const minidump::Module *> filtered_modules = m_minidump_parser->GetFilteredModuleList(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); for (auto module : filtered_modules) { std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString( diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index 3501d38a0f27..5360269199cd 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -75,9 +75,6 @@ public: ArchSpec GetArchitecture(); - Status GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo &range_info) override; - Status GetMemoryRegions( lldb_private::MemoryRegionInfos ®ion_list) override; @@ -98,6 +95,9 @@ protected: bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; + Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) override; + void ReadModuleList(); lldb::ModuleSP GetOrCreateModule(lldb_private::UUID minidump_uuid, diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp index 38d7de77e3bf..7681002c6fb8 100644 --- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp +++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp @@ -27,7 +27,7 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_32( const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo(); - lldb::DataBufferSP result_context_buf( + lldb::WritableDataBufferSP result_context_buf( new DataBufferHeap(target_reg_interface->GetGPRSize(), 0)); uint8_t *result_base = result_context_buf->GetBytes(); diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp index 3c593f0db6ec..917140cab297 100644 --- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp +++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp @@ -50,7 +50,7 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64( const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo(); - lldb::DataBufferSP result_context_buf( + lldb::WritableDataBufferSP result_context_buf( new DataBufferHeap(target_reg_interface->GetGPRSize(), 0)); uint8_t *result_base = result_context_buf->GetBytes(); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index 5eb7cb0e6a5c..cd2d4fe4fd23 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -20,6 +20,7 @@ #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/State.h" #include <mutex> @@ -66,8 +67,7 @@ lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, if (error.Fail() || !process_sp || !process_sp->m_script_object_sp || !process_sp->m_script_object_sp->IsValid()) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "%s", - error.AsCString()); + LLDB_LOGF(GetLog(LLDBLog::Process), "%s", error.AsCString()); return nullptr; } @@ -170,12 +170,13 @@ Status ScriptedProcess::DoLaunch(Module *exe_module, void ScriptedProcess::DidLaunch() { CheckInterpreterAndScriptObject(); m_pid = GetInterface().GetProcessID(); + GetLoadedDynamicLibrariesInfos(); } Status ScriptedProcess::DoResume() { CheckInterpreterAndScriptObject(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // FIXME: Fetch data from thread. const StateType thread_resume_state = eStateRunning; LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__, @@ -199,7 +200,7 @@ Status ScriptedProcess::DoResume() { Status ScriptedProcess::DoStop() { CheckInterpreterAndScriptObject(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (GetInterface().ShouldStop()) { SetPrivateState(eStateStopped); @@ -245,8 +246,8 @@ ArchSpec ScriptedProcess::GetArchitecture() { return GetTarget().GetArchitecture(); } -Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion) { +Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion) { CheckInterpreterAndScriptObject(); Status error; @@ -308,27 +309,50 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, LLVM_PRETTY_FUNCTION, "Couldn't fetch thread list from Scripted Process.", error); + // Because `StructuredData::Dictionary` uses a `std::map<ConstString, + // ObjectSP>` for storage, each item is sorted based on the key alphabetical + // order. Since `GetThreadsInfo` provides thread indices as the key element, + // thread info comes ordered alphabetically, instead of numerically, so we + // need to sort the thread indices before creating thread. + + StructuredData::ArraySP keys = thread_info_sp->GetKeys(); + + std::map<size_t, StructuredData::ObjectSP> sorted_threads; + auto sort_keys = [&sorted_threads, + &thread_info_sp](StructuredData::Object *item) -> bool { + if (!item) + return false; + + llvm::StringRef key = item->GetStringValue(); + size_t idx = 0; + + // Make sure the provided index is actually an integer + if (!llvm::to_integer(key, idx)) + return false; + + sorted_threads[idx] = thread_info_sp->GetValueForKey(key); + return true; + }; + + size_t thread_count = thread_info_sp->GetSize(); + + if (!keys->ForEach(sort_keys) || sorted_threads.size() != thread_count) + // Might be worth showing the unsorted thread list instead of return early. + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, "Couldn't sort thread list.", error); + auto create_scripted_thread = - [this, &old_thread_list, &error, - &new_thread_list](ConstString key, StructuredData::Object *val) -> bool { - if (!val) - return ScriptedInterface::ErrorWithMessage<bool>( - LLVM_PRETTY_FUNCTION, "Invalid thread info object", error); + [this, &error, &new_thread_list]( + const std::pair<size_t, StructuredData::ObjectSP> pair) -> bool { + size_t idx = pair.first; + StructuredData::ObjectSP object_sp = pair.second; - lldb::tid_t tid = LLDB_INVALID_THREAD_ID; - if (!llvm::to_integer(key.AsCString(), tid)) + if (!object_sp) return ScriptedInterface::ErrorWithMessage<bool>( - LLVM_PRETTY_FUNCTION, "Invalid thread id", error); - - if (ThreadSP thread_sp = - old_thread_list.FindThreadByID(tid, false /*=can_update*/)) { - // If the thread was already in the old_thread_list, - // just add it back to the new_thread_list. - new_thread_list.AddThread(thread_sp); - return true; - } + LLVM_PRETTY_FUNCTION, "Invalid thread info object", error); - auto thread_or_error = ScriptedThread::Create(*this, val->GetAsGeneric()); + auto thread_or_error = + ScriptedThread::Create(*this, object_sp->GetAsGeneric()); if (!thread_or_error) return ScriptedInterface::ErrorWithMessage<bool>( @@ -341,8 +365,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, if (!reg_ctx_sp) return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, - llvm::Twine("Invalid Register Context for thread " + - llvm::Twine(key.AsCString())) + llvm::Twine("Invalid Register Context for thread " + llvm::Twine(idx)) .str(), error); @@ -351,7 +374,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, return true; }; - thread_info_sp->ForEach(create_scripted_thread); + llvm::for_each(sorted_threads, create_scripted_thread); return new_thread_list.GetSize(false) > 0; } @@ -359,6 +382,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, void ScriptedProcess::RefreshStateAfterStop() { // Let all threads recover from stopping and do any clean up based on the // previous thread state (if any). + m_thread_list.RefreshStateAfterStop(); } bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { @@ -374,6 +398,93 @@ bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { return true; } +lldb_private::StructuredData::ObjectSP +ScriptedProcess::GetLoadedDynamicLibrariesInfos() { + CheckInterpreterAndScriptObject(); + + Status error; + auto error_with_message = [&error](llvm::StringRef message) { + return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, + message.data(), error); + }; + + StructuredData::ArraySP loaded_images_sp = GetInterface().GetLoadedImages(); + + if (!loaded_images_sp || !loaded_images_sp->GetSize()) + return GetInterface().ErrorWithMessage<StructuredData::ObjectSP>( + LLVM_PRETTY_FUNCTION, "No loaded images.", error); + + ModuleList module_list; + Target &target = GetTarget(); + + auto reload_image = [&target, &module_list, &error_with_message]( + StructuredData::Object *obj) -> bool { + StructuredData::Dictionary *dict = obj->GetAsDictionary(); + + if (!dict) + return error_with_message("Couldn't cast image object into dictionary."); + + ModuleSpec module_spec; + llvm::StringRef value; + + bool has_path = dict->HasKey("path"); + bool has_uuid = dict->HasKey("uuid"); + if (!has_path && !has_uuid) + return error_with_message("Dictionary should have key 'path' or 'uuid'"); + if (!dict->HasKey("load_addr")) + return error_with_message("Dictionary is missing key 'load_addr'"); + + if (has_path) { + dict->GetValueForKeyAsString("path", value); + module_spec.GetFileSpec().SetPath(value); + } + + if (has_uuid) { + dict->GetValueForKeyAsString("uuid", value); + module_spec.GetUUID().SetFromStringRef(value); + } + module_spec.GetArchitecture() = target.GetArchitecture(); + + ModuleSP module_sp = + target.GetOrCreateModule(module_spec, true /* notify */); + + if (!module_sp) + return error_with_message("Couldn't create or get module."); + + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t slide = LLDB_INVALID_OFFSET; + dict->GetValueForKeyAsInteger("load_addr", load_addr); + dict->GetValueForKeyAsInteger("slide", slide); + if (load_addr == LLDB_INVALID_ADDRESS) + return error_with_message( + "Couldn't get valid load address or slide offset."); + + if (slide != LLDB_INVALID_OFFSET) + load_addr += slide; + + bool changed = false; + module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/, + changed); + + if (!changed && !module_sp->GetObjectFile()) + return error_with_message("Couldn't set the load address for module."); + + dict->GetValueForKeyAsString("path", value); + FileSpec objfile(value); + module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename()); + + return module_list.AppendIfNeeded(module_sp); + }; + + if (!loaded_images_sp->ForEach(reload_image)) + return GetInterface().ErrorWithMessage<StructuredData::ObjectSP>( + LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error); + + target.ModulesDidLoad(module_list); + + return loaded_images_sp; +} + ScriptedProcessInterface &ScriptedProcess::GetInterface() const { return m_interpreter->GetScriptedProcessInterface(); } diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h index d56658a2e48a..7edd95e230a1 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -84,14 +84,14 @@ public: ArchSpec GetArchitecture(); - Status GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo &range_info) override; - Status GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override; bool GetProcessInfo(ProcessInstanceInfo &info) override; + lldb_private::StructuredData::ObjectSP + GetLoadedDynamicLibrariesInfos() override; + protected: Status DoStop(); @@ -100,6 +100,9 @@ protected: bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; + Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) override; + private: friend class ScriptedThread; diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index b6cbb62fd6e6..e28f66015dd5 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -15,9 +15,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - +#include "lldb/Utility/LLDBLog.h" #include <memory> using namespace lldb; @@ -123,25 +121,25 @@ ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { llvm::Optional<std::string> reg_data = GetInterface()->GetRegisterContext(); if (!reg_data) - return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>( LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.", - error, LIBLLDB_LOG_THREAD); + error, LLDBLog::Thread); DataBufferSP data_sp( std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size())); if (!data_sp->GetByteSize()) - return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>( LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); std::shared_ptr<RegisterContextMemory> reg_ctx_memory = std::make_shared<RegisterContextMemory>( *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); if (!reg_ctx_memory) - return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>( LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); reg_ctx_memory->SetAllRegisterData(data_sp); m_reg_context_sp = reg_ctx_memory; @@ -149,30 +147,97 @@ ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { return m_reg_context_sp; } +bool ScriptedThread::LoadArtificialStackFrames() { + StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames(); + + Status error; + if (!arr_sp) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.", + error, LLDBLog::Thread); + + size_t arr_size = arr_sp->GetSize(); + if (arr_size > std::numeric_limits<uint32_t>::max()) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine( + "StackFrame array size (" + llvm::Twine(arr_size) + + llvm::Twine( + ") is greater than maximum autorized for a StackFrameList.")) + .str(), + error, LLDBLog::Thread); + + StackFrameListSP frames = GetStackFrameList(); + + for (size_t idx = 0; idx < arr_size; idx++) { + + StructuredData::Dictionary *dict; + + if (!arr_sp->GetItemAtIndexAsDictionary(idx, dict) || !dict) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine( + "Couldn't get artificial stackframe dictionary at index (" + + llvm::Twine(idx) + llvm::Twine(") from stackframe array.")) + .str(), + error, LLDBLog::Thread); + + lldb::addr_t pc; + if (!dict->GetValueForKeyAsInteger("pc", pc)) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + "Couldn't find value for key 'pc' in stackframe dictionary.", error, + LLDBLog::Thread); + + Address symbol_addr; + symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget()); + + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; + bool cfa_is_valid = false; + const bool behaves_like_zeroth_frame = false; + SymbolContext sc; + symbol_addr.CalculateSymbolContext(&sc); + + StackFrameSP synth_frame_sp = std::make_shared<StackFrame>( + this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, + StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc); + + if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp)) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) + + llvm::Twine(") to ScriptedThread StackFrameList.")) + .str(), + error, LLDBLog::Thread); + } + + return true; +} + bool ScriptedThread::CalculateStopInfo() { StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason(); Status error; if (!dict_sp) - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); lldb::StopInfoSP stop_info_sp; lldb::StopReason stop_reason_type; if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'type' in stop reason dictionary.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); StructuredData::Dictionary *data_dict; if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'data' in stop reason dictionary.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); switch (stop_reason_type) { case lldb::eStopReasonNone: @@ -201,12 +266,12 @@ bool ScriptedThread::CalculateStopInfo() { StopInfo::CreateStopReasonWithException(*this, description.data()); } break; default: - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, llvm::Twine("Unsupported stop reason type (" + llvm::Twine(stop_reason_type) + llvm::Twine(").")) .str(), - error, LIBLLDB_LOG_THREAD); + error, LLDBLog::Thread); } if (!stop_info_sp) @@ -218,6 +283,7 @@ bool ScriptedThread::CalculateStopInfo() { void ScriptedThread::RefreshStateAfterStop() { GetRegisterContext()->InvalidateIfNeeded(/*force=*/false); + LoadArtificialStackFrames(); } lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const { @@ -236,7 +302,7 @@ std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() { ->ErrorWithMessage<std::shared_ptr<DynamicRegisterInfo>>( LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); m_register_info_sp = std::make_shared<DynamicRegisterInfo>( *reg_info, m_scripted_process.GetTarget().GetArchitecture()); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h index 8d8a7c2a3df9..959f498edf24 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -42,6 +42,8 @@ public: lldb::RegisterContextSP CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; + bool LoadArtificialStackFrames(); + bool CalculateStopInfo() override; const char *GetInfo() override { return nullptr; } |
