#include "lldb/Host/Config.h"
#include <cerrno>
#include <cstdlib>
#if LLDB_ENABLE_POSIX
#include <netinet/in.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#include <sys/stat.h>
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
#include <ctime>
#include <sys/types.h>
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Breakpoint/WatchpointAlgorithms.h"
#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/RegisterFlags.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include <algorithm>
#include <csignal>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <sstream>
#include <thread>
#include "GDBRemoteRegisterContext.h"
#include "GDBRemoteRegisterFallback.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUGSERVER_BASENAME …
usingnamespacelldb;
usingnamespacelldb_private;
usingnamespacelldb_private::process_gdb_remote;
LLDB_PLUGIN_DEFINE(…)
namespace lldb {
void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { … }
}
namespace {
#define LLDB_PROPERTIES_processgdbremote
#include "ProcessGDBRemoteProperties.inc"
enum { … };
class PluginProperties : public Properties { … };
}
static PluginProperties &GetGlobalPluginProperties() { … }
#if defined(__APPLE__)
#define LOW_PORT …
#define HIGH_PORT …
#else
#define LOW_PORT …
#define HIGH_PORT …
#endif
llvm::StringRef ProcessGDBRemote::GetPluginDescriptionStatic() { … }
void ProcessGDBRemote::Terminate() { … }
lldb::ProcessSP ProcessGDBRemote::CreateInstance(
lldb::TargetSP target_sp, ListenerSP listener_sp,
const FileSpec *crash_file_path, bool can_connect) { … }
void ProcessGDBRemote::DumpPluginHistory(Stream &s) { … }
std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() { … }
ArchSpec ProcessGDBRemote::GetSystemArchitecture() { … }
bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) { … }
ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
ListenerSP listener_sp)
: … { … }
ProcessGDBRemote::~ProcessGDBRemote() { … }
bool ProcessGDBRemote::ParsePythonTargetDefinition(
const FileSpec &target_definition_fspec) { … }
static size_t SplitCommaSeparatedRegisterNumberString(
const llvm::StringRef &comma_separated_register_numbers,
std::vector<uint32_t> ®nums, int base) { … }
void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { … }
Status ProcessGDBRemote::DoWillLaunch(lldb_private::Module *module) { … }
Status ProcessGDBRemote::DoWillAttachToProcessWithID(lldb::pid_t pid) { … }
Status ProcessGDBRemote::DoWillAttachToProcessWithName(const char *process_name,
bool wait_for_launch) { … }
Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { … }
Status ProcessGDBRemote::WillLaunchOrAttach() { … }
Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
ProcessLaunchInfo &launch_info) { … }
Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { … }
void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { … }
void ProcessGDBRemote::LoadStubBinaries() { … }
void ProcessGDBRemote::MaybeLoadExecutableModule() { … }
void ProcessGDBRemote::DidLaunch() { … }
Status ProcessGDBRemote::DoAttachToProcessWithID(
lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) { … }
Status ProcessGDBRemote::DoAttachToProcessWithName(
const char *process_name, const ProcessAttachInfo &attach_info) { … }
llvm::Expected<TraceSupportedResponse> ProcessGDBRemote::TraceSupported() { … }
llvm::Error ProcessGDBRemote::TraceStop(const TraceStopRequest &request) { … }
llvm::Error ProcessGDBRemote::TraceStart(const llvm::json::Value &request) { … }
llvm::Expected<std::string>
ProcessGDBRemote::TraceGetState(llvm::StringRef type) { … }
llvm::Expected<std::vector<uint8_t>>
ProcessGDBRemote::TraceGetBinaryData(const TraceGetBinaryDataRequest &request) { … }
void ProcessGDBRemote::DidExit() { … }
void ProcessGDBRemote::DidAttach(ArchSpec &process_arch) { … }
Status ProcessGDBRemote::WillResume() { … }
Status ProcessGDBRemote::DoResume() { … }
void ProcessGDBRemote::ClearThreadIDList() { … }
size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(
llvm::StringRef value) { … }
size_t ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(
llvm::StringRef value) { … }
bool ProcessGDBRemote::UpdateThreadIDList() { … }
bool ProcessGDBRemote::DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) { … }
void ProcessGDBRemote::SetThreadPc(const ThreadSP &thread_sp, uint64_t index) { … }
bool ProcessGDBRemote::GetThreadStopInfoFromJSON(
ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp) { … }
bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) { … }
void ProcessGDBRemote::ParseExpeditedRegisters(
ExpeditedRegisterMap &expedited_register_map, ThreadSP thread_sp) { … }
ThreadSP ProcessGDBRemote::SetThreadStopInfo(
lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,
uint8_t signo, const std::string &thread_name, const std::string &reason,
const std::string &description, uint32_t exc_type,
const std::vector<addr_t> &exc_data, addr_t thread_dispatch_qaddr,
bool queue_vars_valid,
LazyBool associated_with_dispatch_queue, addr_t dispatch_queue_t,
std::string &queue_name, QueueKind queue_kind, uint64_t queue_serial) { … }
ThreadSP
ProcessGDBRemote::HandleThreadAsyncInterrupt(uint8_t signo,
const std::string &description) { … }
lldb::ThreadSP
ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { … }
StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { … }
void ProcessGDBRemote::RefreshStateAfterStop() { … }
Status ProcessGDBRemote::DoHalt(bool &caused_stop) { … }
Status ProcessGDBRemote::DoDetach(bool keep_stopped) { … }
Status ProcessGDBRemote::DoDestroy() { … }
void ProcessGDBRemote::SetLastStopPacket(
const StringExtractorGDBRemote &response) { … }
void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) { … }
bool ProcessGDBRemote::IsAlive() { … }
addr_t ProcessGDBRemote::GetImageInfoAddress() { … }
void ProcessGDBRemote::WillPublicStop() { … }
size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
Status &error) { … }
bool ProcessGDBRemote::SupportsMemoryTagging() { … }
llvm::Expected<std::vector<uint8_t>>
ProcessGDBRemote::DoReadMemoryTags(lldb::addr_t addr, size_t len,
int32_t type) { … }
Status ProcessGDBRemote::DoWriteMemoryTags(lldb::addr_t addr, size_t len,
int32_t type,
const std::vector<uint8_t> &tags) { … }
Status ProcessGDBRemote::WriteObjectFile(
std::vector<ObjectFile::LoadableData> entries) { … }
bool ProcessGDBRemote::HasErased(FlashRange range) { … }
Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) { … }
Status ProcessGDBRemote::FlashDone() { … }
size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
size_t size, Status &error) { … }
lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
uint32_t permissions,
Status &error) { … }
Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr,
MemoryRegionInfo ®ion_info) { … }
std::optional<uint32_t> ProcessGDBRemote::GetWatchpointSlotCount() { … }
std::optional<bool> ProcessGDBRemote::DoGetWatchpointReportedAfter() { … }
Status ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) { … }
size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,
Status &error) { … }
Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { … }
Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) { … }
static GDBStoppointType
GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp) { … }
Status ProcessGDBRemote::EnableWatchpoint(WatchpointSP wp_sp, bool notify) { … }
Status ProcessGDBRemote::DisableWatchpoint(WatchpointSP wp_sp, bool notify) { … }
void ProcessGDBRemote::Clear() { … }
Status ProcessGDBRemote::DoSignal(int signo) { … }
Status
ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { … }
#if !defined(_WIN32)
#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION …
#endif
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
static bool SetCloexecFlag(int fd) { … }
#endif
Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
const ProcessInfo &process_info) { … }
void ProcessGDBRemote::MonitorDebugserverProcess(
std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
int signo,
int exit_status
) { … }
void ProcessGDBRemote::KillDebugserverProcess() { … }
void ProcessGDBRemote::Initialize() { … }
void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) { … }
bool ProcessGDBRemote::StartAsyncThread() { … }
void ProcessGDBRemote::StopAsyncThread() { … }
thread_result_t ProcessGDBRemote::AsyncThread() { … }
bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
lldb::user_id_t break_loc_id) { … }
Status ProcessGDBRemote::UpdateAutomaticSignalFiltering() { … }
bool ProcessGDBRemote::StartNoticingNewThreads() { … }
bool ProcessGDBRemote::StopNoticingNewThreads() { … }
DynamicLoader *ProcessGDBRemote::GetDynamicLoader() { … }
Status ProcessGDBRemote::SendEventData(const char *data) { … }
DataExtractor ProcessGDBRemote::GetAuxvData() { … }
StructuredData::ObjectSP
ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) { … }
StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
lldb::addr_t image_list_address, lldb::addr_t image_count) { … }
StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos() { … }
StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
const std::vector<lldb::addr_t> &load_addresses) { … }
StructuredData::ObjectSP
ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
StructuredData::ObjectSP args_dict) { … }
StructuredData::ObjectSP ProcessGDBRemote::GetDynamicLoaderProcessState() { … }
StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { … }
Status ProcessGDBRemote::ConfigureStructuredData(
llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) { … }
void ProcessGDBRemote::GetMaxMemorySize() { … }
void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize(
uint64_t user_specified_max) { … }
bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
const ArchSpec &arch,
ModuleSpec &module_spec) { … }
void ProcessGDBRemote::PrefetchModuleSpecs(
llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) { … }
llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() { … }
llvm::VersionTuple ProcessGDBRemote::GetHostMacCatalystVersion() { … }
namespace {
stringVec;
GDBServerRegisterVec;
struct RegisterSetInfo { … };
RegisterSetMap;
struct GdbServerTargetInfo { … };
static FieldEnum::Enumerators ParseEnumEvalues(const XMLNode &enum_node) { … }
static void
ParseEnums(XMLNode feature_node,
llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) { … }
static std::vector<RegisterFlags::Field> ParseFlagsFields(
XMLNode flags_node, unsigned size,
const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) { … }
void ParseFlags(
XMLNode feature_node,
llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) { … }
bool ParseRegisters(
XMLNode feature_node, GdbServerTargetInfo &target_info,
std::vector<DynamicRegisterInfo::Register> ®isters,
llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) { … }
}
bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
ArchSpec &arch_to_use, std::string xml_filename,
std::vector<DynamicRegisterInfo::Register> ®isters) { … }
void ProcessGDBRemote::AddRemoteRegisters(
std::vector<DynamicRegisterInfo::Register> ®isters,
const ArchSpec &arch_to_use) { … }
bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { … }
llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { … }
lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
lldb::addr_t link_map,
lldb::addr_t base_addr,
bool value_is_offset) { … }
llvm::Error ProcessGDBRemote::LoadModules() { … }
Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
bool &is_loaded,
lldb::addr_t &load_addr) { … }
void ProcessGDBRemote::ModulesDidLoad(ModuleList &module_list) { … }
void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out) { … }
static const char *end_delimiter = …;
static const int end_delimiter_len = …;
void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data) { … }
std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(
StringExtractorGDBRemote &profileDataExtractor) { … }
void ProcessGDBRemote::HandleStopReply() { … }
llvm::Expected<bool> ProcessGDBRemote::SaveCore(llvm::StringRef outfile) { … }
static const char *const s_async_json_packet_prefix = …;
static StructuredData::ObjectSP
ParseStructuredDataPacket(llvm::StringRef packet) { … }
void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data) { … }
class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed { … };
class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed { … };
class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed { … };
class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed { … };
class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw { … };
class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword { … };
class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword { … };
CommandObject *ProcessGDBRemote::GetPluginCommandObject() { … }
void ProcessGDBRemote::DidForkSwitchSoftwareBreakpoints(bool enable) { … }
void ProcessGDBRemote::DidForkSwitchHardwareTraps(bool enable) { … }
void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) { … }
void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) { … }
void ProcessGDBRemote::DidVForkDone() { … }
void ProcessGDBRemote::DidExec() { … }