Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
39642 views
//===-- ProcessGDBRemote.cpp ----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Host/Config.h"910#include <cerrno>11#include <cstdlib>12#if LLDB_ENABLE_POSIX13#include <netinet/in.h>14#include <sys/mman.h>15#include <sys/socket.h>16#include <unistd.h>17#endif18#include <sys/stat.h>19#if defined(__APPLE__)20#include <sys/sysctl.h>21#endif22#include <ctime>23#include <sys/types.h>2425#include "lldb/Breakpoint/Watchpoint.h"26#include "lldb/Breakpoint/WatchpointAlgorithms.h"27#include "lldb/Breakpoint/WatchpointResource.h"28#include "lldb/Core/Debugger.h"29#include "lldb/Core/Module.h"30#include "lldb/Core/ModuleSpec.h"31#include "lldb/Core/PluginManager.h"32#include "lldb/Core/Value.h"33#include "lldb/DataFormatters/FormatManager.h"34#include "lldb/Host/ConnectionFileDescriptor.h"35#include "lldb/Host/FileSystem.h"36#include "lldb/Host/HostThread.h"37#include "lldb/Host/PosixApi.h"38#include "lldb/Host/PseudoTerminal.h"39#include "lldb/Host/StreamFile.h"40#include "lldb/Host/ThreadLauncher.h"41#include "lldb/Host/XML.h"42#include "lldb/Interpreter/CommandInterpreter.h"43#include "lldb/Interpreter/CommandObject.h"44#include "lldb/Interpreter/CommandObjectMultiword.h"45#include "lldb/Interpreter/CommandReturnObject.h"46#include "lldb/Interpreter/OptionArgParser.h"47#include "lldb/Interpreter/OptionGroupBoolean.h"48#include "lldb/Interpreter/OptionGroupUInt64.h"49#include "lldb/Interpreter/OptionValueProperties.h"50#include "lldb/Interpreter/Options.h"51#include "lldb/Interpreter/Property.h"52#include "lldb/Symbol/ObjectFile.h"53#include "lldb/Target/ABI.h"54#include "lldb/Target/DynamicLoader.h"55#include "lldb/Target/MemoryRegionInfo.h"56#include "lldb/Target/RegisterFlags.h"57#include "lldb/Target/SystemRuntime.h"58#include "lldb/Target/Target.h"59#include "lldb/Target/TargetList.h"60#include "lldb/Target/ThreadPlanCallFunction.h"61#include "lldb/Utility/Args.h"62#include "lldb/Utility/FileSpec.h"63#include "lldb/Utility/LLDBLog.h"64#include "lldb/Utility/State.h"65#include "lldb/Utility/StreamString.h"66#include "lldb/Utility/Timer.h"67#include <algorithm>68#include <csignal>69#include <map>70#include <memory>71#include <mutex>72#include <optional>73#include <sstream>74#include <thread>7576#include "GDBRemoteRegisterContext.h"77#include "GDBRemoteRegisterFallback.h"78#include "Plugins/Process/Utility/GDBRemoteSignals.h"79#include "Plugins/Process/Utility/InferiorCallPOSIX.h"80#include "Plugins/Process/Utility/StopInfoMachException.h"81#include "ProcessGDBRemote.h"82#include "ProcessGDBRemoteLog.h"83#include "ThreadGDBRemote.h"84#include "lldb/Host/Host.h"85#include "lldb/Utility/StringExtractorGDBRemote.h"8687#include "llvm/ADT/ScopeExit.h"88#include "llvm/ADT/StringMap.h"89#include "llvm/ADT/StringSwitch.h"90#include "llvm/Support/FormatAdapters.h"91#include "llvm/Support/Threading.h"92#include "llvm/Support/raw_ostream.h"9394#define DEBUGSERVER_BASENAME "debugserver"95using namespace lldb;96using namespace lldb_private;97using namespace lldb_private::process_gdb_remote;9899LLDB_PLUGIN_DEFINE(ProcessGDBRemote)100101namespace lldb {102// Provide a function that can easily dump the packet history if we know a103// ProcessGDBRemote * value (which we can get from logs or from debugging). We104// need the function in the lldb namespace so it makes it into the final105// executable since the LLDB shared library only exports stuff in the lldb106// namespace. This allows you to attach with a debugger and call this function107// and get the packet history dumped to a file.108void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {109auto file = FileSystem::Instance().Open(110FileSpec(path), File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate);111if (!file) {112llvm::consumeError(file.takeError());113return;114}115StreamFile stream(std::move(file.get()));116((Process *)p)->DumpPluginHistory(stream);117}118} // namespace lldb119120namespace {121122#define LLDB_PROPERTIES_processgdbremote123#include "ProcessGDBRemoteProperties.inc"124125enum {126#define LLDB_PROPERTIES_processgdbremote127#include "ProcessGDBRemotePropertiesEnum.inc"128};129130class PluginProperties : public Properties {131public:132static llvm::StringRef GetSettingName() {133return ProcessGDBRemote::GetPluginNameStatic();134}135136PluginProperties() : Properties() {137m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());138m_collection_sp->Initialize(g_processgdbremote_properties);139}140141~PluginProperties() override = default;142143uint64_t GetPacketTimeout() {144const uint32_t idx = ePropertyPacketTimeout;145return GetPropertyAtIndexAs<uint64_t>(146idx, g_processgdbremote_properties[idx].default_uint_value);147}148149bool SetPacketTimeout(uint64_t timeout) {150const uint32_t idx = ePropertyPacketTimeout;151return SetPropertyAtIndex(idx, timeout);152}153154FileSpec GetTargetDefinitionFile() const {155const uint32_t idx = ePropertyTargetDefinitionFile;156return GetPropertyAtIndexAs<FileSpec>(idx, {});157}158159bool GetUseSVR4() const {160const uint32_t idx = ePropertyUseSVR4;161return GetPropertyAtIndexAs<bool>(162idx, g_processgdbremote_properties[idx].default_uint_value != 0);163}164165bool GetUseGPacketForReading() const {166const uint32_t idx = ePropertyUseGPacketForReading;167return GetPropertyAtIndexAs<bool>(idx, true);168}169};170171} // namespace172173static PluginProperties &GetGlobalPluginProperties() {174static PluginProperties g_settings;175return g_settings;176}177178// TODO Randomly assigning a port is unsafe. We should get an unused179// ephemeral port from the kernel and make sure we reserve it before passing it180// to debugserver.181182#if defined(__APPLE__)183#define LOW_PORT (IPPORT_RESERVED)184#define HIGH_PORT (IPPORT_HIFIRSTAUTO)185#else186#define LOW_PORT (1024u)187#define HIGH_PORT (49151u)188#endif189190llvm::StringRef ProcessGDBRemote::GetPluginDescriptionStatic() {191return "GDB Remote protocol based debugging plug-in.";192}193194void ProcessGDBRemote::Terminate() {195PluginManager::UnregisterPlugin(ProcessGDBRemote::CreateInstance);196}197198lldb::ProcessSP ProcessGDBRemote::CreateInstance(199lldb::TargetSP target_sp, ListenerSP listener_sp,200const FileSpec *crash_file_path, bool can_connect) {201lldb::ProcessSP process_sp;202if (crash_file_path == nullptr)203process_sp = std::shared_ptr<ProcessGDBRemote>(204new ProcessGDBRemote(target_sp, listener_sp));205return process_sp;206}207208void ProcessGDBRemote::DumpPluginHistory(Stream &s) {209GDBRemoteCommunicationClient &gdb_comm(GetGDBRemote());210gdb_comm.DumpHistory(s);211}212213std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() {214return std::chrono::seconds(GetGlobalPluginProperties().GetPacketTimeout());215}216217ArchSpec ProcessGDBRemote::GetSystemArchitecture() {218return m_gdb_comm.GetHostArchitecture();219}220221bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,222bool plugin_specified_by_name) {223if (plugin_specified_by_name)224return true;225226// For now we are just making sure the file exists for a given module227Module *exe_module = target_sp->GetExecutableModulePointer();228if (exe_module) {229ObjectFile *exe_objfile = exe_module->GetObjectFile();230// We can't debug core files...231switch (exe_objfile->GetType()) {232case ObjectFile::eTypeInvalid:233case ObjectFile::eTypeCoreFile:234case ObjectFile::eTypeDebugInfo:235case ObjectFile::eTypeObjectFile:236case ObjectFile::eTypeSharedLibrary:237case ObjectFile::eTypeStubLibrary:238case ObjectFile::eTypeJIT:239return false;240case ObjectFile::eTypeExecutable:241case ObjectFile::eTypeDynamicLinker:242case ObjectFile::eTypeUnknown:243break;244}245return FileSystem::Instance().Exists(exe_module->GetFileSpec());246}247// However, if there is no executable module, we return true since we might248// be preparing to attach.249return true;250}251252// ProcessGDBRemote constructor253ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,254ListenerSP listener_sp)255: Process(target_sp, listener_sp),256m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_register_info_sp(nullptr),257m_async_broadcaster(nullptr, "lldb.process.gdb-remote.async-broadcaster"),258m_async_listener_sp(259Listener::MakeListener("lldb.process.gdb-remote.async-listener")),260m_async_thread_state_mutex(), m_thread_ids(), m_thread_pcs(),261m_jstopinfo_sp(), m_jthreadsinfo_sp(), m_continue_c_tids(),262m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(),263m_max_memory_size(0), m_remote_stub_max_memory_size(0),264m_addr_to_mmap_size(), m_thread_create_bp_sp(),265m_waiting_for_attach(false), m_command_sp(), m_breakpoint_pc_offset(0),266m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false),267m_erased_flash_ranges(), m_vfork_in_progress_count(0) {268m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,269"async thread should exit");270m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,271"async thread continue");272m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit,273"async thread did exit");274275Log *log = GetLog(GDBRLog::Async);276277const uint32_t async_event_mask =278eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;279280if (m_async_listener_sp->StartListeningForEvents(281&m_async_broadcaster, async_event_mask) != async_event_mask) {282LLDB_LOGF(log,283"ProcessGDBRemote::%s failed to listen for "284"m_async_broadcaster events",285__FUNCTION__);286}287288const uint64_t timeout_seconds =289GetGlobalPluginProperties().GetPacketTimeout();290if (timeout_seconds > 0)291m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));292293m_use_g_packet_for_reading =294GetGlobalPluginProperties().GetUseGPacketForReading();295}296297// Destructor298ProcessGDBRemote::~ProcessGDBRemote() {299// m_mach_process.UnregisterNotificationCallbacks (this);300Clear();301// We need to call finalize on the process before destroying ourselves to302// make sure all of the broadcaster cleanup goes as planned. If we destruct303// this class, then Process::~Process() might have problems trying to fully304// destroy the broadcaster.305Finalize(true /* destructing */);306307// The general Finalize is going to try to destroy the process and that308// SHOULD shut down the async thread. However, if we don't kill it it will309// get stranded and its connection will go away so when it wakes up it will310// crash. So kill it for sure here.311StopAsyncThread();312KillDebugserverProcess();313}314315bool ProcessGDBRemote::ParsePythonTargetDefinition(316const FileSpec &target_definition_fspec) {317ScriptInterpreter *interpreter =318GetTarget().GetDebugger().GetScriptInterpreter();319Status error;320StructuredData::ObjectSP module_object_sp(321interpreter->LoadPluginModule(target_definition_fspec, error));322if (module_object_sp) {323StructuredData::DictionarySP target_definition_sp(324interpreter->GetDynamicSettings(module_object_sp, &GetTarget(),325"gdb-server-target-definition", error));326327if (target_definition_sp) {328StructuredData::ObjectSP target_object(329target_definition_sp->GetValueForKey("host-info"));330if (target_object) {331if (auto host_info_dict = target_object->GetAsDictionary()) {332StructuredData::ObjectSP triple_value =333host_info_dict->GetValueForKey("triple");334if (auto triple_string_value = triple_value->GetAsString()) {335std::string triple_string =336std::string(triple_string_value->GetValue());337ArchSpec host_arch(triple_string.c_str());338if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) {339GetTarget().SetArchitecture(host_arch);340}341}342}343}344m_breakpoint_pc_offset = 0;345StructuredData::ObjectSP breakpoint_pc_offset_value =346target_definition_sp->GetValueForKey("breakpoint-pc-offset");347if (breakpoint_pc_offset_value) {348if (auto breakpoint_pc_int_value =349breakpoint_pc_offset_value->GetAsSignedInteger())350m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();351}352353if (m_register_info_sp->SetRegisterInfo(354*target_definition_sp, GetTarget().GetArchitecture()) > 0) {355return true;356}357}358}359return false;360}361362static size_t SplitCommaSeparatedRegisterNumberString(363const llvm::StringRef &comma_separated_register_numbers,364std::vector<uint32_t> ®nums, int base) {365regnums.clear();366for (llvm::StringRef x : llvm::split(comma_separated_register_numbers, ',')) {367uint32_t reg;368if (llvm::to_integer(x, reg, base))369regnums.push_back(reg);370}371return regnums.size();372}373374void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {375if (!force && m_register_info_sp)376return;377378m_register_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>();379380// Check if qHostInfo specified a specific packet timeout for this381// connection. If so then lets update our setting so the user knows what the382// timeout is and can see it.383const auto host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();384if (host_packet_timeout > std::chrono::seconds(0)) {385GetGlobalPluginProperties().SetPacketTimeout(host_packet_timeout.count());386}387388// Register info search order:389// 1 - Use the target definition python file if one is specified.390// 2 - If the target definition doesn't have any of the info from the391// target.xml (registers) then proceed to read the target.xml.392// 3 - Fall back on the qRegisterInfo packets.393// 4 - Use hardcoded defaults if available.394395FileSpec target_definition_fspec =396GetGlobalPluginProperties().GetTargetDefinitionFile();397if (!FileSystem::Instance().Exists(target_definition_fspec)) {398// If the filename doesn't exist, it may be a ~ not having been expanded -399// try to resolve it.400FileSystem::Instance().Resolve(target_definition_fspec);401}402if (target_definition_fspec) {403// See if we can get register definitions from a python file404if (ParsePythonTargetDefinition(target_definition_fspec))405return;406407Debugger::ReportError("target description file " +408target_definition_fspec.GetPath() +409" failed to parse",410GetTarget().GetDebugger().GetID());411}412413const ArchSpec &target_arch = GetTarget().GetArchitecture();414const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();415const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();416417// Use the process' architecture instead of the host arch, if available418ArchSpec arch_to_use;419if (remote_process_arch.IsValid())420arch_to_use = remote_process_arch;421else422arch_to_use = remote_host_arch;423424if (!arch_to_use.IsValid())425arch_to_use = target_arch;426427if (GetGDBServerRegisterInfo(arch_to_use))428return;429430char packet[128];431std::vector<DynamicRegisterInfo::Register> registers;432uint32_t reg_num = 0;433for (StringExtractorGDBRemote::ResponseType response_type =434StringExtractorGDBRemote::eResponse;435response_type == StringExtractorGDBRemote::eResponse; ++reg_num) {436const int packet_len =437::snprintf(packet, sizeof(packet), "qRegisterInfo%x", reg_num);438assert(packet_len < (int)sizeof(packet));439UNUSED_IF_ASSERT_DISABLED(packet_len);440StringExtractorGDBRemote response;441if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==442GDBRemoteCommunication::PacketResult::Success) {443response_type = response.GetResponseType();444if (response_type == StringExtractorGDBRemote::eResponse) {445llvm::StringRef name;446llvm::StringRef value;447DynamicRegisterInfo::Register reg_info;448449while (response.GetNameColonValue(name, value)) {450if (name == "name") {451reg_info.name.SetString(value);452} else if (name == "alt-name") {453reg_info.alt_name.SetString(value);454} else if (name == "bitsize") {455if (!value.getAsInteger(0, reg_info.byte_size))456reg_info.byte_size /= CHAR_BIT;457} else if (name == "offset") {458value.getAsInteger(0, reg_info.byte_offset);459} else if (name == "encoding") {460const Encoding encoding = Args::StringToEncoding(value);461if (encoding != eEncodingInvalid)462reg_info.encoding = encoding;463} else if (name == "format") {464if (!OptionArgParser::ToFormat(value.str().c_str(), reg_info.format, nullptr)465.Success())466reg_info.format =467llvm::StringSwitch<Format>(value)468.Case("binary", eFormatBinary)469.Case("decimal", eFormatDecimal)470.Case("hex", eFormatHex)471.Case("float", eFormatFloat)472.Case("vector-sint8", eFormatVectorOfSInt8)473.Case("vector-uint8", eFormatVectorOfUInt8)474.Case("vector-sint16", eFormatVectorOfSInt16)475.Case("vector-uint16", eFormatVectorOfUInt16)476.Case("vector-sint32", eFormatVectorOfSInt32)477.Case("vector-uint32", eFormatVectorOfUInt32)478.Case("vector-float32", eFormatVectorOfFloat32)479.Case("vector-uint64", eFormatVectorOfUInt64)480.Case("vector-uint128", eFormatVectorOfUInt128)481.Default(eFormatInvalid);482} else if (name == "set") {483reg_info.set_name.SetString(value);484} else if (name == "gcc" || name == "ehframe") {485value.getAsInteger(0, reg_info.regnum_ehframe);486} else if (name == "dwarf") {487value.getAsInteger(0, reg_info.regnum_dwarf);488} else if (name == "generic") {489reg_info.regnum_generic = Args::StringToGenericRegister(value);490} else if (name == "container-regs") {491SplitCommaSeparatedRegisterNumberString(value, reg_info.value_regs, 16);492} else if (name == "invalidate-regs") {493SplitCommaSeparatedRegisterNumberString(value, reg_info.invalidate_regs, 16);494}495}496497assert(reg_info.byte_size != 0);498registers.push_back(reg_info);499} else {500break; // ensure exit before reg_num is incremented501}502} else {503break;504}505}506507if (registers.empty())508registers = GetFallbackRegisters(arch_to_use);509510AddRemoteRegisters(registers, arch_to_use);511}512513Status ProcessGDBRemote::DoWillLaunch(lldb_private::Module *module) {514return WillLaunchOrAttach();515}516517Status ProcessGDBRemote::DoWillAttachToProcessWithID(lldb::pid_t pid) {518return WillLaunchOrAttach();519}520521Status ProcessGDBRemote::DoWillAttachToProcessWithName(const char *process_name,522bool wait_for_launch) {523return WillLaunchOrAttach();524}525526Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {527Log *log = GetLog(GDBRLog::Process);528529Status error(WillLaunchOrAttach());530if (error.Fail())531return error;532533error = ConnectToDebugserver(remote_url);534if (error.Fail())535return error;536537StartAsyncThread();538539lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();540if (pid == LLDB_INVALID_PROCESS_ID) {541// We don't have a valid process ID, so note that we are connected and542// could now request to launch or attach, or get remote process listings...543SetPrivateState(eStateConnected);544} else {545// We have a valid process546SetID(pid);547GetThreadList();548StringExtractorGDBRemote response;549if (m_gdb_comm.GetStopReply(response)) {550SetLastStopPacket(response);551552Target &target = GetTarget();553if (!target.GetArchitecture().IsValid()) {554if (m_gdb_comm.GetProcessArchitecture().IsValid()) {555target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());556} else {557if (m_gdb_comm.GetHostArchitecture().IsValid()) {558target.SetArchitecture(m_gdb_comm.GetHostArchitecture());559}560}561}562563const StateType state = SetThreadStopInfo(response);564if (state != eStateInvalid) {565SetPrivateState(state);566} else567error.SetErrorStringWithFormat(568"Process %" PRIu64 " was reported after connecting to "569"'%s', but state was not stopped: %s",570pid, remote_url.str().c_str(), StateAsCString(state));571} else572error.SetErrorStringWithFormat("Process %" PRIu64573" was reported after connecting to '%s', "574"but no stop reply packet was received",575pid, remote_url.str().c_str());576}577578LLDB_LOGF(log,579"ProcessGDBRemote::%s pid %" PRIu64580": normalizing target architecture initial triple: %s "581"(GetTarget().GetArchitecture().IsValid() %s, "582"m_gdb_comm.GetHostArchitecture().IsValid(): %s)",583__FUNCTION__, GetID(),584GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),585GetTarget().GetArchitecture().IsValid() ? "true" : "false",586m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");587588if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&589m_gdb_comm.GetHostArchitecture().IsValid()) {590// Prefer the *process'* architecture over that of the *host*, if591// available.592if (m_gdb_comm.GetProcessArchitecture().IsValid())593GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());594else595GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());596}597598LLDB_LOGF(log,599"ProcessGDBRemote::%s pid %" PRIu64600": normalized target architecture triple: %s",601__FUNCTION__, GetID(),602GetTarget().GetArchitecture().GetTriple().getTriple().c_str());603604return error;605}606607Status ProcessGDBRemote::WillLaunchOrAttach() {608Status error;609m_stdio_communication.Clear();610return error;611}612613// Process Control614Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,615ProcessLaunchInfo &launch_info) {616Log *log = GetLog(GDBRLog::Process);617Status error;618619LLDB_LOGF(log, "ProcessGDBRemote::%s() entered", __FUNCTION__);620621uint32_t launch_flags = launch_info.GetFlags().Get();622FileSpec stdin_file_spec{};623FileSpec stdout_file_spec{};624FileSpec stderr_file_spec{};625FileSpec working_dir = launch_info.GetWorkingDirectory();626627const FileAction *file_action;628file_action = launch_info.GetFileActionForFD(STDIN_FILENO);629if (file_action) {630if (file_action->GetAction() == FileAction::eFileActionOpen)631stdin_file_spec = file_action->GetFileSpec();632}633file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);634if (file_action) {635if (file_action->GetAction() == FileAction::eFileActionOpen)636stdout_file_spec = file_action->GetFileSpec();637}638file_action = launch_info.GetFileActionForFD(STDERR_FILENO);639if (file_action) {640if (file_action->GetAction() == FileAction::eFileActionOpen)641stderr_file_spec = file_action->GetFileSpec();642}643644if (log) {645if (stdin_file_spec || stdout_file_spec || stderr_file_spec)646LLDB_LOGF(log,647"ProcessGDBRemote::%s provided with STDIO paths via "648"launch_info: stdin=%s, stdout=%s, stderr=%s",649__FUNCTION__,650stdin_file_spec ? stdin_file_spec.GetPath().c_str() : "<null>",651stdout_file_spec ? stdout_file_spec.GetPath().c_str() : "<null>",652stderr_file_spec ? stderr_file_spec.GetPath().c_str() : "<null>");653else654LLDB_LOGF(log,655"ProcessGDBRemote::%s no STDIO paths given via launch_info",656__FUNCTION__);657}658659const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;660if (stdin_file_spec || disable_stdio) {661// the inferior will be reading stdin from the specified file or stdio is662// completely disabled663m_stdin_forward = false;664} else {665m_stdin_forward = true;666}667668// ::LogSetBitMask (GDBR_LOG_DEFAULT);669// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE |670// LLDB_LOG_OPTION_PREPEND_TIMESTAMP |671// LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);672// ::LogSetLogFile ("/dev/stdout");673674error = EstablishConnectionIfNeeded(launch_info);675if (error.Success()) {676PseudoTerminal pty;677const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;678679PlatformSP platform_sp(GetTarget().GetPlatform());680if (disable_stdio) {681// set to /dev/null unless redirected to a file above682if (!stdin_file_spec)683stdin_file_spec.SetFile(FileSystem::DEV_NULL,684FileSpec::Style::native);685if (!stdout_file_spec)686stdout_file_spec.SetFile(FileSystem::DEV_NULL,687FileSpec::Style::native);688if (!stderr_file_spec)689stderr_file_spec.SetFile(FileSystem::DEV_NULL,690FileSpec::Style::native);691} else if (platform_sp && platform_sp->IsHost()) {692// If the debugserver is local and we aren't disabling STDIO, lets use693// a pseudo terminal to instead of relying on the 'O' packets for stdio694// since 'O' packets can really slow down debugging if the inferior695// does a lot of output.696if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&697!errorToBool(pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY))) {698FileSpec secondary_name(pty.GetSecondaryName());699700if (!stdin_file_spec)701stdin_file_spec = secondary_name;702703if (!stdout_file_spec)704stdout_file_spec = secondary_name;705706if (!stderr_file_spec)707stderr_file_spec = secondary_name;708}709LLDB_LOGF(710log,711"ProcessGDBRemote::%s adjusted STDIO paths for local platform "712"(IsHost() is true) using secondary: stdin=%s, stdout=%s, "713"stderr=%s",714__FUNCTION__,715stdin_file_spec ? stdin_file_spec.GetPath().c_str() : "<null>",716stdout_file_spec ? stdout_file_spec.GetPath().c_str() : "<null>",717stderr_file_spec ? stderr_file_spec.GetPath().c_str() : "<null>");718}719720LLDB_LOGF(log,721"ProcessGDBRemote::%s final STDIO paths after all "722"adjustments: stdin=%s, stdout=%s, stderr=%s",723__FUNCTION__,724stdin_file_spec ? stdin_file_spec.GetPath().c_str() : "<null>",725stdout_file_spec ? stdout_file_spec.GetPath().c_str() : "<null>",726stderr_file_spec ? stderr_file_spec.GetPath().c_str() : "<null>");727728if (stdin_file_spec)729m_gdb_comm.SetSTDIN(stdin_file_spec);730if (stdout_file_spec)731m_gdb_comm.SetSTDOUT(stdout_file_spec);732if (stderr_file_spec)733m_gdb_comm.SetSTDERR(stderr_file_spec);734735m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);736m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);737738m_gdb_comm.SendLaunchArchPacket(739GetTarget().GetArchitecture().GetArchitectureName());740741const char *launch_event_data = launch_info.GetLaunchEventData();742if (launch_event_data != nullptr && *launch_event_data != '\0')743m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);744745if (working_dir) {746m_gdb_comm.SetWorkingDir(working_dir);747}748749// Send the environment and the program + arguments after we connect750m_gdb_comm.SendEnvironment(launch_info.GetEnvironment());751752{753// Scope for the scoped timeout object754GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm,755std::chrono::seconds(10));756757// Since we can't send argv0 separate from the executable path, we need to758// make sure to use the actual executable path found in the launch_info...759Args args = launch_info.GetArguments();760if (FileSpec exe_file = launch_info.GetExecutableFile())761args.ReplaceArgumentAtIndex(0, exe_file.GetPath(false));762if (llvm::Error err = m_gdb_comm.LaunchProcess(args)) {763error.SetErrorStringWithFormatv("Cannot launch '{0}': {1}",764args.GetArgumentAtIndex(0),765llvm::fmt_consume(std::move(err)));766} else {767SetID(m_gdb_comm.GetCurrentProcessID());768}769}770771if (GetID() == LLDB_INVALID_PROCESS_ID) {772LLDB_LOGF(log, "failed to connect to debugserver: %s",773error.AsCString());774KillDebugserverProcess();775return error;776}777778StringExtractorGDBRemote response;779if (m_gdb_comm.GetStopReply(response)) {780SetLastStopPacket(response);781782const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();783784if (process_arch.IsValid()) {785GetTarget().MergeArchitecture(process_arch);786} else {787const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();788if (host_arch.IsValid())789GetTarget().MergeArchitecture(host_arch);790}791792SetPrivateState(SetThreadStopInfo(response));793794if (!disable_stdio) {795if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd)796SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor());797}798}799} else {800LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString());801}802return error;803}804805Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {806Status error;807// Only connect if we have a valid connect URL808Log *log = GetLog(GDBRLog::Process);809810if (!connect_url.empty()) {811LLDB_LOGF(log, "ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,812connect_url.str().c_str());813std::unique_ptr<ConnectionFileDescriptor> conn_up(814new ConnectionFileDescriptor());815if (conn_up) {816const uint32_t max_retry_count = 50;817uint32_t retry_count = 0;818while (!m_gdb_comm.IsConnected()) {819if (conn_up->Connect(connect_url, &error) == eConnectionStatusSuccess) {820m_gdb_comm.SetConnection(std::move(conn_up));821break;822}823824retry_count++;825826if (retry_count >= max_retry_count)827break;828829std::this_thread::sleep_for(std::chrono::milliseconds(100));830}831}832}833834if (!m_gdb_comm.IsConnected()) {835if (error.Success())836error.SetErrorString("not connected to remote gdb server");837return error;838}839840// We always seem to be able to open a connection to a local port so we need841// to make sure we can then send data to it. If we can't then we aren't842// actually connected to anything, so try and do the handshake with the843// remote GDB server and make sure that goes alright.844if (!m_gdb_comm.HandshakeWithServer(&error)) {845m_gdb_comm.Disconnect();846if (error.Success())847error.SetErrorString("not connected to remote gdb server");848return error;849}850851m_gdb_comm.GetEchoSupported();852m_gdb_comm.GetThreadSuffixSupported();853m_gdb_comm.GetListThreadsInStopReplySupported();854m_gdb_comm.GetHostInfo();855m_gdb_comm.GetVContSupported('c');856m_gdb_comm.GetVAttachOrWaitSupported();857m_gdb_comm.EnableErrorStringInPacket();858859// First dispatch any commands from the platform:860auto handle_cmds = [&] (const Args &args) -> void {861for (const Args::ArgEntry &entry : args) {862StringExtractorGDBRemote response;863m_gdb_comm.SendPacketAndWaitForResponse(864entry.c_str(), response);865}866};867868PlatformSP platform_sp = GetTarget().GetPlatform();869if (platform_sp) {870handle_cmds(platform_sp->GetExtraStartupCommands());871}872873// Then dispatch any process commands:874handle_cmds(GetExtraStartupCommands());875876return error;877}878879void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {880Log *log = GetLog(GDBRLog::Process);881BuildDynamicRegisterInfo(false);882883// See if the GDB server supports qHostInfo or qProcessInfo packets. Prefer884// qProcessInfo as it will be more specific to our process.885886const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();887if (remote_process_arch.IsValid()) {888process_arch = remote_process_arch;889LLDB_LOG(log, "gdb-remote had process architecture, using {0} {1}",890process_arch.GetArchitectureName(),891process_arch.GetTriple().getTriple());892} else {893process_arch = m_gdb_comm.GetHostArchitecture();894LLDB_LOG(log,895"gdb-remote did not have process architecture, using gdb-remote "896"host architecture {0} {1}",897process_arch.GetArchitectureName(),898process_arch.GetTriple().getTriple());899}900901AddressableBits addressable_bits = m_gdb_comm.GetAddressableBits();902SetAddressableBitMasks(addressable_bits);903904if (process_arch.IsValid()) {905const ArchSpec &target_arch = GetTarget().GetArchitecture();906if (target_arch.IsValid()) {907LLDB_LOG(log, "analyzing target arch, currently {0} {1}",908target_arch.GetArchitectureName(),909target_arch.GetTriple().getTriple());910911// If the remote host is ARM and we have apple as the vendor, then912// ARM executables and shared libraries can have mixed ARM913// architectures.914// You can have an armv6 executable, and if the host is armv7, then the915// system will load the best possible architecture for all shared916// libraries it has, so we really need to take the remote host917// architecture as our defacto architecture in this case.918919if ((process_arch.GetMachine() == llvm::Triple::arm ||920process_arch.GetMachine() == llvm::Triple::thumb) &&921process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {922GetTarget().SetArchitecture(process_arch);923LLDB_LOG(log,924"remote process is ARM/Apple, "925"setting target arch to {0} {1}",926process_arch.GetArchitectureName(),927process_arch.GetTriple().getTriple());928} else {929// Fill in what is missing in the triple930const llvm::Triple &remote_triple = process_arch.GetTriple();931llvm::Triple new_target_triple = target_arch.GetTriple();932if (new_target_triple.getVendorName().size() == 0) {933new_target_triple.setVendor(remote_triple.getVendor());934935if (new_target_triple.getOSName().size() == 0) {936new_target_triple.setOS(remote_triple.getOS());937938if (new_target_triple.getEnvironmentName().size() == 0)939new_target_triple.setEnvironment(remote_triple.getEnvironment());940}941942ArchSpec new_target_arch = target_arch;943new_target_arch.SetTriple(new_target_triple);944GetTarget().SetArchitecture(new_target_arch);945}946}947948LLDB_LOG(log,949"final target arch after adjustments for remote architecture: "950"{0} {1}",951target_arch.GetArchitectureName(),952target_arch.GetTriple().getTriple());953} else {954// The target doesn't have a valid architecture yet, set it from the955// architecture we got from the remote GDB server956GetTarget().SetArchitecture(process_arch);957}958}959960// Target and Process are reasonably initailized;961// load any binaries we have metadata for / set load address.962LoadStubBinaries();963MaybeLoadExecutableModule();964965// Find out which StructuredDataPlugins are supported by the debug monitor.966// These plugins transmit data over async $J packets.967if (StructuredData::Array *supported_packets =968m_gdb_comm.GetSupportedStructuredDataPlugins())969MapSupportedStructuredDataPlugins(*supported_packets);970971// If connected to LLDB ("native-signals+"), use signal defs for972// the remote platform. If connected to GDB, just use the standard set.973if (!m_gdb_comm.UsesNativeSignals()) {974SetUnixSignals(std::make_shared<GDBRemoteSignals>());975} else {976PlatformSP platform_sp = GetTarget().GetPlatform();977if (platform_sp && platform_sp->IsConnected())978SetUnixSignals(platform_sp->GetUnixSignals());979else980SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));981}982}983984void ProcessGDBRemote::LoadStubBinaries() {985// The remote stub may know about the "main binary" in986// the context of a firmware debug session, and can987// give us a UUID and an address/slide of where the988// binary is loaded in memory.989UUID standalone_uuid;990addr_t standalone_value;991bool standalone_value_is_offset;992if (m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,993standalone_value_is_offset)) {994ModuleSP module_sp;995996if (standalone_uuid.IsValid()) {997const bool force_symbol_search = true;998const bool notify = true;999const bool set_address_in_target = true;1000const bool allow_memory_image_last_resort = false;1001DynamicLoader::LoadBinaryWithUUIDAndAddress(1002this, "", standalone_uuid, standalone_value,1003standalone_value_is_offset, force_symbol_search, notify,1004set_address_in_target, allow_memory_image_last_resort);1005}1006}10071008// The remote stub may know about a list of binaries to1009// force load into the process -- a firmware type situation1010// where multiple binaries are present in virtual memory,1011// and we are only given the addresses of the binaries.1012// Not intended for use with userland debugging, when we use1013// a DynamicLoader plugin that knows how to find the loaded1014// binaries, and will track updates as binaries are added.10151016std::vector<addr_t> bin_addrs = m_gdb_comm.GetProcessStandaloneBinaries();1017if (bin_addrs.size()) {1018UUID uuid;1019const bool value_is_slide = false;1020for (addr_t addr : bin_addrs) {1021const bool notify = true;1022// First see if this is a special platform1023// binary that may determine the DynamicLoader and1024// Platform to be used in this Process and Target.1025if (GetTarget()1026.GetDebugger()1027.GetPlatformList()1028.LoadPlatformBinaryAndSetup(this, addr, notify))1029continue;10301031const bool force_symbol_search = true;1032const bool set_address_in_target = true;1033const bool allow_memory_image_last_resort = false;1034// Second manually load this binary into the Target.1035DynamicLoader::LoadBinaryWithUUIDAndAddress(1036this, llvm::StringRef(), uuid, addr, value_is_slide,1037force_symbol_search, notify, set_address_in_target,1038allow_memory_image_last_resort);1039}1040}1041}10421043void ProcessGDBRemote::MaybeLoadExecutableModule() {1044ModuleSP module_sp = GetTarget().GetExecutableModule();1045if (!module_sp)1046return;10471048std::optional<QOffsets> offsets = m_gdb_comm.GetQOffsets();1049if (!offsets)1050return;10511052bool is_uniform =1053size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==1054offsets->offsets.size();1055if (!is_uniform)1056return; // TODO: Handle non-uniform responses.10571058bool changed = false;1059module_sp->SetLoadAddress(GetTarget(), offsets->offsets[0],1060/*value_is_offset=*/true, changed);1061if (changed) {1062ModuleList list;1063list.Append(module_sp);1064m_process->GetTarget().ModulesDidLoad(list);1065}1066}10671068void ProcessGDBRemote::DidLaunch() {1069ArchSpec process_arch;1070DidLaunchOrAttach(process_arch);1071}10721073Status ProcessGDBRemote::DoAttachToProcessWithID(1074lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) {1075Log *log = GetLog(GDBRLog::Process);1076Status error;10771078LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__);10791080// Clear out and clean up from any current state1081Clear();1082if (attach_pid != LLDB_INVALID_PROCESS_ID) {1083error = EstablishConnectionIfNeeded(attach_info);1084if (error.Success()) {1085m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());10861087char packet[64];1088const int packet_len =1089::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);1090SetID(attach_pid);1091auto data_sp =1092std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));1093m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue, data_sp);1094} else1095SetExitStatus(-1, error.AsCString());1096}10971098return error;1099}11001101Status ProcessGDBRemote::DoAttachToProcessWithName(1102const char *process_name, const ProcessAttachInfo &attach_info) {1103Status error;1104// Clear out and clean up from any current state1105Clear();11061107if (process_name && process_name[0]) {1108error = EstablishConnectionIfNeeded(attach_info);1109if (error.Success()) {1110StreamString packet;11111112m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());11131114if (attach_info.GetWaitForLaunch()) {1115if (!m_gdb_comm.GetVAttachOrWaitSupported()) {1116packet.PutCString("vAttachWait");1117} else {1118if (attach_info.GetIgnoreExisting())1119packet.PutCString("vAttachWait");1120else1121packet.PutCString("vAttachOrWait");1122}1123} else1124packet.PutCString("vAttachName");1125packet.PutChar(';');1126packet.PutBytesAsRawHex8(process_name, strlen(process_name),1127endian::InlHostByteOrder(),1128endian::InlHostByteOrder());11291130auto data_sp = std::make_shared<EventDataBytes>(packet.GetString());1131m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue, data_sp);11321133} else1134SetExitStatus(-1, error.AsCString());1135}1136return error;1137}11381139llvm::Expected<TraceSupportedResponse> ProcessGDBRemote::TraceSupported() {1140return m_gdb_comm.SendTraceSupported(GetInterruptTimeout());1141}11421143llvm::Error ProcessGDBRemote::TraceStop(const TraceStopRequest &request) {1144return m_gdb_comm.SendTraceStop(request, GetInterruptTimeout());1145}11461147llvm::Error ProcessGDBRemote::TraceStart(const llvm::json::Value &request) {1148return m_gdb_comm.SendTraceStart(request, GetInterruptTimeout());1149}11501151llvm::Expected<std::string>1152ProcessGDBRemote::TraceGetState(llvm::StringRef type) {1153return m_gdb_comm.SendTraceGetState(type, GetInterruptTimeout());1154}11551156llvm::Expected<std::vector<uint8_t>>1157ProcessGDBRemote::TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {1158return m_gdb_comm.SendTraceGetBinaryData(request, GetInterruptTimeout());1159}11601161void ProcessGDBRemote::DidExit() {1162// When we exit, disconnect from the GDB server communications1163m_gdb_comm.Disconnect();1164}11651166void ProcessGDBRemote::DidAttach(ArchSpec &process_arch) {1167// If you can figure out what the architecture is, fill it in here.1168process_arch.Clear();1169DidLaunchOrAttach(process_arch);1170}11711172Status ProcessGDBRemote::WillResume() {1173m_continue_c_tids.clear();1174m_continue_C_tids.clear();1175m_continue_s_tids.clear();1176m_continue_S_tids.clear();1177m_jstopinfo_sp.reset();1178m_jthreadsinfo_sp.reset();1179return Status();1180}11811182Status ProcessGDBRemote::DoResume() {1183Status error;1184Log *log = GetLog(GDBRLog::Process);1185LLDB_LOGF(log, "ProcessGDBRemote::Resume()");11861187ListenerSP listener_sp(1188Listener::MakeListener("gdb-remote.resume-packet-sent"));1189if (listener_sp->StartListeningForEvents(1190&m_gdb_comm, GDBRemoteClientBase::eBroadcastBitRunPacketSent)) {1191listener_sp->StartListeningForEvents(1192&m_async_broadcaster,1193ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);11941195const size_t num_threads = GetThreadList().GetSize();11961197StreamString continue_packet;1198bool continue_packet_error = false;1199if (m_gdb_comm.HasAnyVContSupport()) {1200std::string pid_prefix;1201if (m_gdb_comm.GetMultiprocessSupported())1202pid_prefix = llvm::formatv("p{0:x-}.", GetID());12031204if (m_continue_c_tids.size() == num_threads ||1205(m_continue_c_tids.empty() && m_continue_C_tids.empty() &&1206m_continue_s_tids.empty() && m_continue_S_tids.empty())) {1207// All threads are continuing1208if (m_gdb_comm.GetMultiprocessSupported())1209continue_packet.Format("vCont;c:{0}-1", pid_prefix);1210else1211continue_packet.PutCString("c");1212} else {1213continue_packet.PutCString("vCont");12141215if (!m_continue_c_tids.empty()) {1216if (m_gdb_comm.GetVContSupported('c')) {1217for (tid_collection::const_iterator1218t_pos = m_continue_c_tids.begin(),1219t_end = m_continue_c_tids.end();1220t_pos != t_end; ++t_pos)1221continue_packet.Format(";c:{0}{1:x-}", pid_prefix, *t_pos);1222} else1223continue_packet_error = true;1224}12251226if (!continue_packet_error && !m_continue_C_tids.empty()) {1227if (m_gdb_comm.GetVContSupported('C')) {1228for (tid_sig_collection::const_iterator1229s_pos = m_continue_C_tids.begin(),1230s_end = m_continue_C_tids.end();1231s_pos != s_end; ++s_pos)1232continue_packet.Format(";C{0:x-2}:{1}{2:x-}", s_pos->second,1233pid_prefix, s_pos->first);1234} else1235continue_packet_error = true;1236}12371238if (!continue_packet_error && !m_continue_s_tids.empty()) {1239if (m_gdb_comm.GetVContSupported('s')) {1240for (tid_collection::const_iterator1241t_pos = m_continue_s_tids.begin(),1242t_end = m_continue_s_tids.end();1243t_pos != t_end; ++t_pos)1244continue_packet.Format(";s:{0}{1:x-}", pid_prefix, *t_pos);1245} else1246continue_packet_error = true;1247}12481249if (!continue_packet_error && !m_continue_S_tids.empty()) {1250if (m_gdb_comm.GetVContSupported('S')) {1251for (tid_sig_collection::const_iterator1252s_pos = m_continue_S_tids.begin(),1253s_end = m_continue_S_tids.end();1254s_pos != s_end; ++s_pos)1255continue_packet.Format(";S{0:x-2}:{1}{2:x-}", s_pos->second,1256pid_prefix, s_pos->first);1257} else1258continue_packet_error = true;1259}12601261if (continue_packet_error)1262continue_packet.Clear();1263}1264} else1265continue_packet_error = true;12661267if (continue_packet_error) {1268// Either no vCont support, or we tried to use part of the vCont packet1269// that wasn't supported by the remote GDB server. We need to try and1270// make a simple packet that can do our continue1271const size_t num_continue_c_tids = m_continue_c_tids.size();1272const size_t num_continue_C_tids = m_continue_C_tids.size();1273const size_t num_continue_s_tids = m_continue_s_tids.size();1274const size_t num_continue_S_tids = m_continue_S_tids.size();1275if (num_continue_c_tids > 0) {1276if (num_continue_c_tids == num_threads) {1277// All threads are resuming...1278m_gdb_comm.SetCurrentThreadForRun(-1);1279continue_packet.PutChar('c');1280continue_packet_error = false;1281} else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&1282num_continue_s_tids == 0 && num_continue_S_tids == 0) {1283// Only one thread is continuing1284m_gdb_comm.SetCurrentThreadForRun(m_continue_c_tids.front());1285continue_packet.PutChar('c');1286continue_packet_error = false;1287}1288}12891290if (continue_packet_error && num_continue_C_tids > 0) {1291if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&1292num_continue_C_tids > 0 && num_continue_s_tids == 0 &&1293num_continue_S_tids == 0) {1294const int continue_signo = m_continue_C_tids.front().second;1295// Only one thread is continuing1296if (num_continue_C_tids > 1) {1297// More that one thread with a signal, yet we don't have vCont1298// support and we are being asked to resume each thread with a1299// signal, we need to make sure they are all the same signal, or we1300// can't issue the continue accurately with the current support...1301if (num_continue_C_tids > 1) {1302continue_packet_error = false;1303for (size_t i = 1; i < m_continue_C_tids.size(); ++i) {1304if (m_continue_C_tids[i].second != continue_signo)1305continue_packet_error = true;1306}1307}1308if (!continue_packet_error)1309m_gdb_comm.SetCurrentThreadForRun(-1);1310} else {1311// Set the continue thread ID1312continue_packet_error = false;1313m_gdb_comm.SetCurrentThreadForRun(m_continue_C_tids.front().first);1314}1315if (!continue_packet_error) {1316// Add threads continuing with the same signo...1317continue_packet.Printf("C%2.2x", continue_signo);1318}1319}1320}13211322if (continue_packet_error && num_continue_s_tids > 0) {1323if (num_continue_s_tids == num_threads) {1324// All threads are resuming...1325m_gdb_comm.SetCurrentThreadForRun(-1);13261327continue_packet.PutChar('s');13281329continue_packet_error = false;1330} else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&1331num_continue_s_tids == 1 && num_continue_S_tids == 0) {1332// Only one thread is stepping1333m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());1334continue_packet.PutChar('s');1335continue_packet_error = false;1336}1337}13381339if (!continue_packet_error && num_continue_S_tids > 0) {1340if (num_continue_S_tids == num_threads) {1341const int step_signo = m_continue_S_tids.front().second;1342// Are all threads trying to step with the same signal?1343continue_packet_error = false;1344if (num_continue_S_tids > 1) {1345for (size_t i = 1; i < num_threads; ++i) {1346if (m_continue_S_tids[i].second != step_signo)1347continue_packet_error = true;1348}1349}1350if (!continue_packet_error) {1351// Add threads stepping with the same signo...1352m_gdb_comm.SetCurrentThreadForRun(-1);1353continue_packet.Printf("S%2.2x", step_signo);1354}1355} else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&1356num_continue_s_tids == 0 && num_continue_S_tids == 1) {1357// Only one thread is stepping with signal1358m_gdb_comm.SetCurrentThreadForRun(m_continue_S_tids.front().first);1359continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);1360continue_packet_error = false;1361}1362}1363}13641365if (continue_packet_error) {1366error.SetErrorString("can't make continue packet for this resume");1367} else {1368EventSP event_sp;1369if (!m_async_thread.IsJoinable()) {1370error.SetErrorString("Trying to resume but the async thread is dead.");1371LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Trying to resume but the "1372"async thread is dead.");1373return error;1374}13751376auto data_sp =1377std::make_shared<EventDataBytes>(continue_packet.GetString());1378m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue, data_sp);13791380if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {1381error.SetErrorString("Resume timed out.");1382LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Resume timed out.");1383} else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {1384error.SetErrorString("Broadcast continue, but the async thread was "1385"killed before we got an ack back.");1386LLDB_LOGF(log,1387"ProcessGDBRemote::DoResume: Broadcast continue, but the "1388"async thread was killed before we got an ack back.");1389return error;1390}1391}1392}13931394return error;1395}13961397void ProcessGDBRemote::ClearThreadIDList() {1398std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());1399m_thread_ids.clear();1400m_thread_pcs.clear();1401}14021403size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(1404llvm::StringRef value) {1405m_thread_ids.clear();1406lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();1407StringExtractorGDBRemote thread_ids{value};14081409do {1410auto pid_tid = thread_ids.GetPidTid(pid);1411if (pid_tid && pid_tid->first == pid) {1412lldb::tid_t tid = pid_tid->second;1413if (tid != LLDB_INVALID_THREAD_ID &&1414tid != StringExtractorGDBRemote::AllProcesses)1415m_thread_ids.push_back(tid);1416}1417} while (thread_ids.GetChar() == ',');14181419return m_thread_ids.size();1420}14211422size_t ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(1423llvm::StringRef value) {1424m_thread_pcs.clear();1425for (llvm::StringRef x : llvm::split(value, ',')) {1426lldb::addr_t pc;1427if (llvm::to_integer(x, pc, 16))1428m_thread_pcs.push_back(pc);1429}1430return m_thread_pcs.size();1431}14321433bool ProcessGDBRemote::UpdateThreadIDList() {1434std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());14351436if (m_jthreadsinfo_sp) {1437// If we have the JSON threads info, we can get the thread list from that1438StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();1439if (thread_infos && thread_infos->GetSize() > 0) {1440m_thread_ids.clear();1441m_thread_pcs.clear();1442thread_infos->ForEach([this](StructuredData::Object *object) -> bool {1443StructuredData::Dictionary *thread_dict = object->GetAsDictionary();1444if (thread_dict) {1445// Set the thread stop info from the JSON dictionary1446SetThreadStopInfo(thread_dict);1447lldb::tid_t tid = LLDB_INVALID_THREAD_ID;1448if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))1449m_thread_ids.push_back(tid);1450}1451return true; // Keep iterating through all thread_info objects1452});1453}1454if (!m_thread_ids.empty())1455return true;1456} else {1457// See if we can get the thread IDs from the current stop reply packets1458// that might contain a "threads" key/value pair14591460if (m_last_stop_packet) {1461// Get the thread stop info1462StringExtractorGDBRemote &stop_info = *m_last_stop_packet;1463const std::string &stop_info_str = std::string(stop_info.GetStringRef());14641465m_thread_pcs.clear();1466const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");1467if (thread_pcs_pos != std::string::npos) {1468const size_t start = thread_pcs_pos + strlen(";thread-pcs:");1469const size_t end = stop_info_str.find(';', start);1470if (end != std::string::npos) {1471std::string value = stop_info_str.substr(start, end - start);1472UpdateThreadPCsFromStopReplyThreadsValue(value);1473}1474}14751476const size_t threads_pos = stop_info_str.find(";threads:");1477if (threads_pos != std::string::npos) {1478const size_t start = threads_pos + strlen(";threads:");1479const size_t end = stop_info_str.find(';', start);1480if (end != std::string::npos) {1481std::string value = stop_info_str.substr(start, end - start);1482if (UpdateThreadIDsFromStopReplyThreadsValue(value))1483return true;1484}1485}1486}1487}14881489bool sequence_mutex_unavailable = false;1490m_gdb_comm.GetCurrentThreadIDs(m_thread_ids, sequence_mutex_unavailable);1491if (sequence_mutex_unavailable) {1492return false; // We just didn't get the list1493}1494return true;1495}14961497bool ProcessGDBRemote::DoUpdateThreadList(ThreadList &old_thread_list,1498ThreadList &new_thread_list) {1499// locker will keep a mutex locked until it goes out of scope1500Log *log = GetLog(GDBRLog::Thread);1501LLDB_LOGV(log, "pid = {0}", GetID());15021503size_t num_thread_ids = m_thread_ids.size();1504// The "m_thread_ids" thread ID list should always be updated after each stop1505// reply packet, but in case it isn't, update it here.1506if (num_thread_ids == 0) {1507if (!UpdateThreadIDList())1508return false;1509num_thread_ids = m_thread_ids.size();1510}15111512ThreadList old_thread_list_copy(old_thread_list);1513if (num_thread_ids > 0) {1514for (size_t i = 0; i < num_thread_ids; ++i) {1515tid_t tid = m_thread_ids[i];1516ThreadSP thread_sp(1517old_thread_list_copy.RemoveThreadByProtocolID(tid, false));1518if (!thread_sp) {1519thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);1520LLDB_LOGV(log, "Making new thread: {0} for thread ID: {1:x}.",1521thread_sp.get(), thread_sp->GetID());1522} else {1523LLDB_LOGV(log, "Found old thread: {0} for thread ID: {1:x}.",1524thread_sp.get(), thread_sp->GetID());1525}15261527SetThreadPc(thread_sp, i);1528new_thread_list.AddThreadSortedByIndexID(thread_sp);1529}1530}15311532// Whatever that is left in old_thread_list_copy are not present in1533// new_thread_list. Remove non-existent threads from internal id table.1534size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);1535for (size_t i = 0; i < old_num_thread_ids; i++) {1536ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));1537if (old_thread_sp) {1538lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();1539m_thread_id_to_index_id_map.erase(old_thread_id);1540}1541}15421543return true;1544}15451546void ProcessGDBRemote::SetThreadPc(const ThreadSP &thread_sp, uint64_t index) {1547if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() &&1548GetByteOrder() != eByteOrderInvalid) {1549ThreadGDBRemote *gdb_thread =1550static_cast<ThreadGDBRemote *>(thread_sp.get());1551RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());1552if (reg_ctx_sp) {1553uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(1554eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);1555if (pc_regnum != LLDB_INVALID_REGNUM) {1556gdb_thread->PrivateSetRegisterValue(pc_regnum, m_thread_pcs[index]);1557}1558}1559}1560}15611562bool ProcessGDBRemote::GetThreadStopInfoFromJSON(1563ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp) {1564// See if we got thread stop infos for all threads via the "jThreadsInfo"1565// packet1566if (thread_infos_sp) {1567StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();1568if (thread_infos) {1569lldb::tid_t tid;1570const size_t n = thread_infos->GetSize();1571for (size_t i = 0; i < n; ++i) {1572StructuredData::Dictionary *thread_dict =1573thread_infos->GetItemAtIndex(i)->GetAsDictionary();1574if (thread_dict) {1575if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>(1576"tid", tid, LLDB_INVALID_THREAD_ID)) {1577if (tid == thread->GetID())1578return (bool)SetThreadStopInfo(thread_dict);1579}1580}1581}1582}1583}1584return false;1585}15861587bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {1588// See if we got thread stop infos for all threads via the "jThreadsInfo"1589// packet1590if (GetThreadStopInfoFromJSON(thread, m_jthreadsinfo_sp))1591return true;15921593// See if we got thread stop info for any threads valid stop info reasons1594// threads via the "jstopinfo" packet stop reply packet key/value pair?1595if (m_jstopinfo_sp) {1596// If we have "jstopinfo" then we have stop descriptions for all threads1597// that have stop reasons, and if there is no entry for a thread, then it1598// has no stop reason.1599thread->GetRegisterContext()->InvalidateIfNeeded(true);1600if (!GetThreadStopInfoFromJSON(thread, m_jstopinfo_sp)) {1601// If a thread is stopped at a breakpoint site, set that as the stop1602// reason even if it hasn't executed the breakpoint instruction yet.1603// We will silently step over the breakpoint when we resume execution1604// and miss the fact that this thread hit the breakpoint.1605const size_t num_thread_ids = m_thread_ids.size();1606for (size_t i = 0; i < num_thread_ids; i++) {1607if (m_thread_ids[i] == thread->GetID() && m_thread_pcs.size() > i) {1608addr_t pc = m_thread_pcs[i];1609lldb::BreakpointSiteSP bp_site_sp =1610thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);1611if (bp_site_sp) {1612if (bp_site_sp->ValidForThisThread(*thread)) {1613thread->SetStopInfo(1614StopInfo::CreateStopReasonWithBreakpointSiteID(1615*thread, bp_site_sp->GetID()));1616return true;1617}1618}1619}1620}1621thread->SetStopInfo(StopInfoSP());1622}1623return true;1624}16251626// Fall back to using the qThreadStopInfo packet1627StringExtractorGDBRemote stop_packet;1628if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))1629return SetThreadStopInfo(stop_packet) == eStateStopped;1630return false;1631}16321633void ProcessGDBRemote::ParseExpeditedRegisters(1634ExpeditedRegisterMap &expedited_register_map, ThreadSP thread_sp) {1635ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread_sp.get());1636RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext());16371638for (const auto &pair : expedited_register_map) {1639StringExtractor reg_value_extractor(pair.second);1640WritableDataBufferSP buffer_sp(1641new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0));1642reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');1643uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(1644eRegisterKindProcessPlugin, pair.first);1645gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData());1646}1647}16481649ThreadSP ProcessGDBRemote::SetThreadStopInfo(1650lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,1651uint8_t signo, const std::string &thread_name, const std::string &reason,1652const std::string &description, uint32_t exc_type,1653const std::vector<addr_t> &exc_data, addr_t thread_dispatch_qaddr,1654bool queue_vars_valid, // Set to true if queue_name, queue_kind and1655// queue_serial are valid1656LazyBool associated_with_dispatch_queue, addr_t dispatch_queue_t,1657std::string &queue_name, QueueKind queue_kind, uint64_t queue_serial) {16581659if (tid == LLDB_INVALID_THREAD_ID)1660return nullptr;16611662ThreadSP thread_sp;1663// Scope for "locker" below1664{1665// m_thread_list_real does have its own mutex, but we need to hold onto the1666// mutex between the call to m_thread_list_real.FindThreadByID(...) and the1667// m_thread_list_real.AddThread(...) so it doesn't change on us1668std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());1669thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);16701671if (!thread_sp) {1672// Create the thread if we need to1673thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);1674m_thread_list_real.AddThread(thread_sp);1675}1676}16771678ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread_sp.get());1679RegisterContextSP reg_ctx_sp(gdb_thread->GetRegisterContext());16801681reg_ctx_sp->InvalidateIfNeeded(true);16821683auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid);1684if (iter != m_thread_ids.end())1685SetThreadPc(thread_sp, iter - m_thread_ids.begin());16861687ParseExpeditedRegisters(expedited_register_map, thread_sp);16881689if (reg_ctx_sp->ReconfigureRegisterInfo()) {1690// Now we have changed the offsets of all the registers, so the values1691// will be corrupted.1692reg_ctx_sp->InvalidateAllRegisters();1693// Expedited registers values will never contain registers that would be1694// resized by a reconfigure. So we are safe to continue using these1695// values.1696ParseExpeditedRegisters(expedited_register_map, thread_sp);1697}16981699thread_sp->SetName(thread_name.empty() ? nullptr : thread_name.c_str());17001701gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr);1702// Check if the GDB server was able to provide the queue name, kind and serial1703// number1704if (queue_vars_valid)1705gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,1706dispatch_queue_t, associated_with_dispatch_queue);1707else1708gdb_thread->ClearQueueInfo();17091710gdb_thread->SetAssociatedWithLibdispatchQueue(associated_with_dispatch_queue);17111712if (dispatch_queue_t != LLDB_INVALID_ADDRESS)1713gdb_thread->SetQueueLibdispatchQueueAddress(dispatch_queue_t);17141715// Make sure we update our thread stop reason just once, but don't overwrite1716// the stop info for threads that haven't moved:1717StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(false);1718if (thread_sp->GetTemporaryResumeState() == eStateSuspended &&1719current_stop_info_sp) {1720thread_sp->SetStopInfo(current_stop_info_sp);1721return thread_sp;1722}17231724if (!thread_sp->StopInfoIsUpToDate()) {1725thread_sp->SetStopInfo(StopInfoSP());1726// If there's a memory thread backed by this thread, we need to use it to1727// calculate StopInfo.1728if (ThreadSP memory_thread_sp = m_thread_list.GetBackingThread(thread_sp))1729thread_sp = memory_thread_sp;17301731if (exc_type != 0) {1732const size_t exc_data_size = exc_data.size();17331734thread_sp->SetStopInfo(1735StopInfoMachException::CreateStopReasonWithMachException(1736*thread_sp, exc_type, exc_data_size,1737exc_data_size >= 1 ? exc_data[0] : 0,1738exc_data_size >= 2 ? exc_data[1] : 0,1739exc_data_size >= 3 ? exc_data[2] : 0));1740} else {1741bool handled = false;1742bool did_exec = false;1743// debugserver can send reason = "none" which is equivalent1744// to no reason.1745if (!reason.empty() && reason != "none") {1746if (reason == "trace") {1747addr_t pc = thread_sp->GetRegisterContext()->GetPC();1748lldb::BreakpointSiteSP bp_site_sp =1749thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(1750pc);17511752// If the current pc is a breakpoint site then the StopInfo should be1753// set to Breakpoint Otherwise, it will be set to Trace.1754if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {1755thread_sp->SetStopInfo(1756StopInfo::CreateStopReasonWithBreakpointSiteID(1757*thread_sp, bp_site_sp->GetID()));1758} else1759thread_sp->SetStopInfo(1760StopInfo::CreateStopReasonToTrace(*thread_sp));1761handled = true;1762} else if (reason == "breakpoint") {1763addr_t pc = thread_sp->GetRegisterContext()->GetPC();1764lldb::BreakpointSiteSP bp_site_sp =1765thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(1766pc);1767if (bp_site_sp) {1768// If the breakpoint is for this thread, then we'll report the hit,1769// but if it is for another thread, we can just report no reason.1770// We don't need to worry about stepping over the breakpoint here,1771// that will be taken care of when the thread resumes and notices1772// that there's a breakpoint under the pc.1773handled = true;1774if (bp_site_sp->ValidForThisThread(*thread_sp)) {1775thread_sp->SetStopInfo(1776StopInfo::CreateStopReasonWithBreakpointSiteID(1777*thread_sp, bp_site_sp->GetID()));1778} else {1779StopInfoSP invalid_stop_info_sp;1780thread_sp->SetStopInfo(invalid_stop_info_sp);1781}1782}1783} else if (reason == "trap") {1784// Let the trap just use the standard signal stop reason below...1785} else if (reason == "watchpoint") {1786// We will have between 1 and 3 fields in the description.1787//1788// \a wp_addr which is the original start address that1789// lldb requested be watched, or an address that the1790// hardware reported. This address should be within the1791// range of a currently active watchpoint region - lldb1792// should be able to find a watchpoint with this address.1793//1794// \a wp_index is the hardware watchpoint register number.1795//1796// \a wp_hit_addr is the actual address reported by the hardware,1797// which may be outside the range of a region we are watching.1798//1799// On MIPS, we may get a false watchpoint exception where an1800// access to the same 8 byte granule as a watchpoint will trigger,1801// even if the access was not within the range of the watched1802// region. When we get a \a wp_hit_addr outside the range of any1803// set watchpoint, continue execution without making it visible to1804// the user.1805//1806// On ARM, a related issue where a large access that starts1807// before the watched region (and extends into the watched1808// region) may report a hit address before the watched region.1809// lldb will not find the "nearest" watchpoint to1810// disable/step/re-enable it, so one of the valid watchpoint1811// addresses should be provided as \a wp_addr.1812StringExtractor desc_extractor(description.c_str());1813// FIXME NativeThreadLinux::SetStoppedByWatchpoint sends this1814// up as1815// <address within wp range> <wp hw index> <actual accessed addr>1816// but this is not reading the <wp hw index>. Seems like it1817// wouldn't work on MIPS, where that third field is important.1818addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);1819addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);1820watch_id_t watch_id = LLDB_INVALID_WATCH_ID;1821bool silently_continue = false;1822WatchpointResourceSP wp_resource_sp;1823if (wp_hit_addr != LLDB_INVALID_ADDRESS) {1824wp_resource_sp =1825m_watchpoint_resource_list.FindByAddress(wp_hit_addr);1826// On MIPS, \a wp_hit_addr outside the range of a watched1827// region means we should silently continue, it is a false hit.1828ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();1829if (!wp_resource_sp && core >= ArchSpec::kCore_mips_first &&1830core <= ArchSpec::kCore_mips_last)1831silently_continue = true;1832}1833if (!wp_resource_sp && wp_addr != LLDB_INVALID_ADDRESS)1834wp_resource_sp = m_watchpoint_resource_list.FindByAddress(wp_addr);1835if (!wp_resource_sp) {1836Log *log(GetLog(GDBRLog::Watchpoints));1837LLDB_LOGF(log, "failed to find watchpoint");1838watch_id = LLDB_INVALID_SITE_ID;1839} else {1840// LWP_TODO: This is hardcoding a single Watchpoint in a1841// Resource, need to add1842// StopInfo::CreateStopReasonWithWatchpointResource which1843// represents all watchpoints that were tripped at this stop.1844watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();1845}1846thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(1847*thread_sp, watch_id, silently_continue));1848handled = true;1849} else if (reason == "exception") {1850thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(1851*thread_sp, description.c_str()));1852handled = true;1853} else if (reason == "exec") {1854did_exec = true;1855thread_sp->SetStopInfo(1856StopInfo::CreateStopReasonWithExec(*thread_sp));1857handled = true;1858} else if (reason == "processor trace") {1859thread_sp->SetStopInfo(StopInfo::CreateStopReasonProcessorTrace(1860*thread_sp, description.c_str()));1861} else if (reason == "fork") {1862StringExtractor desc_extractor(description.c_str());1863lldb::pid_t child_pid =1864desc_extractor.GetU64(LLDB_INVALID_PROCESS_ID);1865lldb::tid_t child_tid = desc_extractor.GetU64(LLDB_INVALID_THREAD_ID);1866thread_sp->SetStopInfo(1867StopInfo::CreateStopReasonFork(*thread_sp, child_pid, child_tid));1868handled = true;1869} else if (reason == "vfork") {1870StringExtractor desc_extractor(description.c_str());1871lldb::pid_t child_pid =1872desc_extractor.GetU64(LLDB_INVALID_PROCESS_ID);1873lldb::tid_t child_tid = desc_extractor.GetU64(LLDB_INVALID_THREAD_ID);1874thread_sp->SetStopInfo(StopInfo::CreateStopReasonVFork(1875*thread_sp, child_pid, child_tid));1876handled = true;1877} else if (reason == "vforkdone") {1878thread_sp->SetStopInfo(1879StopInfo::CreateStopReasonVForkDone(*thread_sp));1880handled = true;1881}1882} else if (!signo) {1883addr_t pc = thread_sp->GetRegisterContext()->GetPC();1884lldb::BreakpointSiteSP bp_site_sp =1885thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);18861887// If a thread is stopped at a breakpoint site, set that as the stop1888// reason even if it hasn't executed the breakpoint instruction yet.1889// We will silently step over the breakpoint when we resume execution1890// and miss the fact that this thread hit the breakpoint.1891if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {1892thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(1893*thread_sp, bp_site_sp->GetID()));1894handled = true;1895}1896}18971898if (!handled && signo && !did_exec) {1899if (signo == SIGTRAP) {1900// Currently we are going to assume SIGTRAP means we are either1901// hitting a breakpoint or hardware single stepping.1902handled = true;1903addr_t pc =1904thread_sp->GetRegisterContext()->GetPC() + m_breakpoint_pc_offset;1905lldb::BreakpointSiteSP bp_site_sp =1906thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(1907pc);19081909if (bp_site_sp) {1910// If the breakpoint is for this thread, then we'll report the hit,1911// but if it is for another thread, we can just report no reason.1912// We don't need to worry about stepping over the breakpoint here,1913// that will be taken care of when the thread resumes and notices1914// that there's a breakpoint under the pc.1915if (bp_site_sp->ValidForThisThread(*thread_sp)) {1916if (m_breakpoint_pc_offset != 0)1917thread_sp->GetRegisterContext()->SetPC(pc);1918thread_sp->SetStopInfo(1919StopInfo::CreateStopReasonWithBreakpointSiteID(1920*thread_sp, bp_site_sp->GetID()));1921} else {1922StopInfoSP invalid_stop_info_sp;1923thread_sp->SetStopInfo(invalid_stop_info_sp);1924}1925} else {1926// If we were stepping then assume the stop was the result of the1927// trace. If we were not stepping then report the SIGTRAP.1928// FIXME: We are still missing the case where we single step over a1929// trap instruction.1930if (thread_sp->GetTemporaryResumeState() == eStateStepping)1931thread_sp->SetStopInfo(1932StopInfo::CreateStopReasonToTrace(*thread_sp));1933else1934thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(1935*thread_sp, signo, description.c_str()));1936}1937}1938if (!handled)1939thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(1940*thread_sp, signo, description.c_str()));1941}19421943if (!description.empty()) {1944lldb::StopInfoSP stop_info_sp(thread_sp->GetStopInfo());1945if (stop_info_sp) {1946const char *stop_info_desc = stop_info_sp->GetDescription();1947if (!stop_info_desc || !stop_info_desc[0])1948stop_info_sp->SetDescription(description.c_str());1949} else {1950thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(1951*thread_sp, description.c_str()));1952}1953}1954}1955}1956return thread_sp;1957}19581959lldb::ThreadSP1960ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {1961static constexpr llvm::StringLiteral g_key_tid("tid");1962static constexpr llvm::StringLiteral g_key_name("name");1963static constexpr llvm::StringLiteral g_key_reason("reason");1964static constexpr llvm::StringLiteral g_key_metype("metype");1965static constexpr llvm::StringLiteral g_key_medata("medata");1966static constexpr llvm::StringLiteral g_key_qaddr("qaddr");1967static constexpr llvm::StringLiteral g_key_dispatch_queue_t(1968"dispatch_queue_t");1969static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(1970"associated_with_dispatch_queue");1971static constexpr llvm::StringLiteral g_key_queue_name("qname");1972static constexpr llvm::StringLiteral g_key_queue_kind("qkind");1973static constexpr llvm::StringLiteral g_key_queue_serial_number("qserialnum");1974static constexpr llvm::StringLiteral g_key_registers("registers");1975static constexpr llvm::StringLiteral g_key_memory("memory");1976static constexpr llvm::StringLiteral g_key_description("description");1977static constexpr llvm::StringLiteral g_key_signal("signal");19781979// Stop with signal and thread info1980lldb::tid_t tid = LLDB_INVALID_THREAD_ID;1981uint8_t signo = 0;1982std::string value;1983std::string thread_name;1984std::string reason;1985std::string description;1986uint32_t exc_type = 0;1987std::vector<addr_t> exc_data;1988addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;1989ExpeditedRegisterMap expedited_register_map;1990bool queue_vars_valid = false;1991addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;1992LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;1993std::string queue_name;1994QueueKind queue_kind = eQueueKindUnknown;1995uint64_t queue_serial_number = 0;1996// Iterate through all of the thread dictionary key/value pairs from the1997// structured data dictionary19981999// FIXME: we're silently ignoring invalid data here2000thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name,2001&signo, &reason, &description, &exc_type, &exc_data,2002&thread_dispatch_qaddr, &queue_vars_valid,2003&associated_with_dispatch_queue, &dispatch_queue_t,2004&queue_name, &queue_kind, &queue_serial_number](2005llvm::StringRef key,2006StructuredData::Object *object) -> bool {2007if (key == g_key_tid) {2008// thread in big endian hex2009tid = object->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);2010} else if (key == g_key_metype) {2011// exception type in big endian hex2012exc_type = object->GetUnsignedIntegerValue(0);2013} else if (key == g_key_medata) {2014// exception data in big endian hex2015StructuredData::Array *array = object->GetAsArray();2016if (array) {2017array->ForEach([&exc_data](StructuredData::Object *object) -> bool {2018exc_data.push_back(object->GetUnsignedIntegerValue());2019return true; // Keep iterating through all array items2020});2021}2022} else if (key == g_key_name) {2023thread_name = std::string(object->GetStringValue());2024} else if (key == g_key_qaddr) {2025thread_dispatch_qaddr =2026object->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);2027} else if (key == g_key_queue_name) {2028queue_vars_valid = true;2029queue_name = std::string(object->GetStringValue());2030} else if (key == g_key_queue_kind) {2031std::string queue_kind_str = std::string(object->GetStringValue());2032if (queue_kind_str == "serial") {2033queue_vars_valid = true;2034queue_kind = eQueueKindSerial;2035} else if (queue_kind_str == "concurrent") {2036queue_vars_valid = true;2037queue_kind = eQueueKindConcurrent;2038}2039} else if (key == g_key_queue_serial_number) {2040queue_serial_number = object->GetUnsignedIntegerValue(0);2041if (queue_serial_number != 0)2042queue_vars_valid = true;2043} else if (key == g_key_dispatch_queue_t) {2044dispatch_queue_t = object->GetUnsignedIntegerValue(0);2045if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)2046queue_vars_valid = true;2047} else if (key == g_key_associated_with_dispatch_queue) {2048queue_vars_valid = true;2049bool associated = object->GetBooleanValue();2050if (associated)2051associated_with_dispatch_queue = eLazyBoolYes;2052else2053associated_with_dispatch_queue = eLazyBoolNo;2054} else if (key == g_key_reason) {2055reason = std::string(object->GetStringValue());2056} else if (key == g_key_description) {2057description = std::string(object->GetStringValue());2058} else if (key == g_key_registers) {2059StructuredData::Dictionary *registers_dict = object->GetAsDictionary();20602061if (registers_dict) {2062registers_dict->ForEach(2063[&expedited_register_map](llvm::StringRef key,2064StructuredData::Object *object) -> bool {2065uint32_t reg;2066if (llvm::to_integer(key, reg))2067expedited_register_map[reg] =2068std::string(object->GetStringValue());2069return true; // Keep iterating through all array items2070});2071}2072} else if (key == g_key_memory) {2073StructuredData::Array *array = object->GetAsArray();2074if (array) {2075array->ForEach([this](StructuredData::Object *object) -> bool {2076StructuredData::Dictionary *mem_cache_dict =2077object->GetAsDictionary();2078if (mem_cache_dict) {2079lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;2080if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>(2081"address", mem_cache_addr)) {2082if (mem_cache_addr != LLDB_INVALID_ADDRESS) {2083llvm::StringRef str;2084if (mem_cache_dict->GetValueForKeyAsString("bytes", str)) {2085StringExtractor bytes(str);2086bytes.SetFilePos(0);20872088const size_t byte_size = bytes.GetStringRef().size() / 2;2089WritableDataBufferSP data_buffer_sp(2090new DataBufferHeap(byte_size, 0));2091const size_t bytes_copied =2092bytes.GetHexBytes(data_buffer_sp->GetData(), 0);2093if (bytes_copied == byte_size)2094m_memory_cache.AddL1CacheData(mem_cache_addr,2095data_buffer_sp);2096}2097}2098}2099}2100return true; // Keep iterating through all array items2101});2102}21032104} else if (key == g_key_signal)2105signo = object->GetUnsignedIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);2106return true; // Keep iterating through all dictionary key/value pairs2107});21082109return SetThreadStopInfo(tid, expedited_register_map, signo, thread_name,2110reason, description, exc_type, exc_data,2111thread_dispatch_qaddr, queue_vars_valid,2112associated_with_dispatch_queue, dispatch_queue_t,2113queue_name, queue_kind, queue_serial_number);2114}21152116StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {2117lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();2118stop_packet.SetFilePos(0);2119const char stop_type = stop_packet.GetChar();2120switch (stop_type) {2121case 'T':2122case 'S': {2123// This is a bit of a hack, but it is required. If we did exec, we need to2124// clear our thread lists and also know to rebuild our dynamic register2125// info before we lookup and threads and populate the expedited register2126// values so we need to know this right away so we can cleanup and update2127// our registers.2128const uint32_t stop_id = GetStopID();2129if (stop_id == 0) {2130// Our first stop, make sure we have a process ID, and also make sure we2131// know about our registers2132if (GetID() == LLDB_INVALID_PROCESS_ID && pid != LLDB_INVALID_PROCESS_ID)2133SetID(pid);2134BuildDynamicRegisterInfo(true);2135}2136// Stop with signal and thread info2137lldb::pid_t stop_pid = LLDB_INVALID_PROCESS_ID;2138lldb::tid_t tid = LLDB_INVALID_THREAD_ID;2139const uint8_t signo = stop_packet.GetHexU8();2140llvm::StringRef key;2141llvm::StringRef value;2142std::string thread_name;2143std::string reason;2144std::string description;2145uint32_t exc_type = 0;2146std::vector<addr_t> exc_data;2147addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;2148bool queue_vars_valid =2149false; // says if locals below that start with "queue_" are valid2150addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;2151LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;2152std::string queue_name;2153QueueKind queue_kind = eQueueKindUnknown;2154uint64_t queue_serial_number = 0;2155ExpeditedRegisterMap expedited_register_map;2156AddressableBits addressable_bits;2157while (stop_packet.GetNameColonValue(key, value)) {2158if (key.compare("metype") == 0) {2159// exception type in big endian hex2160value.getAsInteger(16, exc_type);2161} else if (key.compare("medata") == 0) {2162// exception data in big endian hex2163uint64_t x;2164value.getAsInteger(16, x);2165exc_data.push_back(x);2166} else if (key.compare("thread") == 0) {2167// thread-id2168StringExtractorGDBRemote thread_id{value};2169auto pid_tid = thread_id.GetPidTid(pid);2170if (pid_tid) {2171stop_pid = pid_tid->first;2172tid = pid_tid->second;2173} else2174tid = LLDB_INVALID_THREAD_ID;2175} else if (key.compare("threads") == 0) {2176std::lock_guard<std::recursive_mutex> guard(2177m_thread_list_real.GetMutex());2178UpdateThreadIDsFromStopReplyThreadsValue(value);2179} else if (key.compare("thread-pcs") == 0) {2180m_thread_pcs.clear();2181// A comma separated list of all threads in the current2182// process that includes the thread for this stop reply packet2183lldb::addr_t pc;2184while (!value.empty()) {2185llvm::StringRef pc_str;2186std::tie(pc_str, value) = value.split(',');2187if (pc_str.getAsInteger(16, pc))2188pc = LLDB_INVALID_ADDRESS;2189m_thread_pcs.push_back(pc);2190}2191} else if (key.compare("jstopinfo") == 0) {2192StringExtractor json_extractor(value);2193std::string json;2194// Now convert the HEX bytes into a string value2195json_extractor.GetHexByteString(json);21962197// This JSON contains thread IDs and thread stop info for all threads.2198// It doesn't contain expedited registers, memory or queue info.2199m_jstopinfo_sp = StructuredData::ParseJSON(json);2200} else if (key.compare("hexname") == 0) {2201StringExtractor name_extractor(value);2202std::string name;2203// Now convert the HEX bytes into a string value2204name_extractor.GetHexByteString(thread_name);2205} else if (key.compare("name") == 0) {2206thread_name = std::string(value);2207} else if (key.compare("qaddr") == 0) {2208value.getAsInteger(16, thread_dispatch_qaddr);2209} else if (key.compare("dispatch_queue_t") == 0) {2210queue_vars_valid = true;2211value.getAsInteger(16, dispatch_queue_t);2212} else if (key.compare("qname") == 0) {2213queue_vars_valid = true;2214StringExtractor name_extractor(value);2215// Now convert the HEX bytes into a string value2216name_extractor.GetHexByteString(queue_name);2217} else if (key.compare("qkind") == 0) {2218queue_kind = llvm::StringSwitch<QueueKind>(value)2219.Case("serial", eQueueKindSerial)2220.Case("concurrent", eQueueKindConcurrent)2221.Default(eQueueKindUnknown);2222queue_vars_valid = queue_kind != eQueueKindUnknown;2223} else if (key.compare("qserialnum") == 0) {2224if (!value.getAsInteger(0, queue_serial_number))2225queue_vars_valid = true;2226} else if (key.compare("reason") == 0) {2227reason = std::string(value);2228} else if (key.compare("description") == 0) {2229StringExtractor desc_extractor(value);2230// Now convert the HEX bytes into a string value2231desc_extractor.GetHexByteString(description);2232} else if (key.compare("memory") == 0) {2233// Expedited memory. GDB servers can choose to send back expedited2234// memory that can populate the L1 memory cache in the process so that2235// things like the frame pointer backchain can be expedited. This will2236// help stack backtracing be more efficient by not having to send as2237// many memory read requests down the remote GDB server.22382239// Key/value pair format: memory:<addr>=<bytes>;2240// <addr> is a number whose base will be interpreted by the prefix:2241// "0x[0-9a-fA-F]+" for hex2242// "0[0-7]+" for octal2243// "[1-9]+" for decimal2244// <bytes> is native endian ASCII hex bytes just like the register2245// values2246llvm::StringRef addr_str, bytes_str;2247std::tie(addr_str, bytes_str) = value.split('=');2248if (!addr_str.empty() && !bytes_str.empty()) {2249lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;2250if (!addr_str.getAsInteger(0, mem_cache_addr)) {2251StringExtractor bytes(bytes_str);2252const size_t byte_size = bytes.GetBytesLeft() / 2;2253WritableDataBufferSP data_buffer_sp(2254new DataBufferHeap(byte_size, 0));2255const size_t bytes_copied =2256bytes.GetHexBytes(data_buffer_sp->GetData(), 0);2257if (bytes_copied == byte_size)2258m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);2259}2260}2261} else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 ||2262key.compare("awatch") == 0) {2263// Support standard GDB remote stop reply packet 'TAAwatch:addr'2264lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;2265value.getAsInteger(16, wp_addr);22662267WatchpointResourceSP wp_resource_sp =2268m_watchpoint_resource_list.FindByAddress(wp_addr);22692270// Rewrite gdb standard watch/rwatch/awatch to2271// "reason:watchpoint" + "description:ADDR",2272// which is parsed in SetThreadStopInfo.2273reason = "watchpoint";2274StreamString ostr;2275ostr.Printf("%" PRIu64, wp_addr);2276description = std::string(ostr.GetString());2277} else if (key.compare("library") == 0) {2278auto error = LoadModules();2279if (error) {2280Log *log(GetLog(GDBRLog::Process));2281LLDB_LOG_ERROR(log, std::move(error), "Failed to load modules: {0}");2282}2283} else if (key.compare("fork") == 0 || key.compare("vfork") == 0) {2284// fork includes child pid/tid in thread-id format2285StringExtractorGDBRemote thread_id{value};2286auto pid_tid = thread_id.GetPidTid(LLDB_INVALID_PROCESS_ID);2287if (!pid_tid) {2288Log *log(GetLog(GDBRLog::Process));2289LLDB_LOG(log, "Invalid PID/TID to fork: {0}", value);2290pid_tid = {{LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID}};2291}22922293reason = key.str();2294StreamString ostr;2295ostr.Printf("%" PRIu64 " %" PRIu64, pid_tid->first, pid_tid->second);2296description = std::string(ostr.GetString());2297} else if (key.compare("addressing_bits") == 0) {2298uint64_t addressing_bits;2299if (!value.getAsInteger(0, addressing_bits)) {2300addressable_bits.SetAddressableBits(addressing_bits);2301}2302} else if (key.compare("low_mem_addressing_bits") == 0) {2303uint64_t addressing_bits;2304if (!value.getAsInteger(0, addressing_bits)) {2305addressable_bits.SetLowmemAddressableBits(addressing_bits);2306}2307} else if (key.compare("high_mem_addressing_bits") == 0) {2308uint64_t addressing_bits;2309if (!value.getAsInteger(0, addressing_bits)) {2310addressable_bits.SetHighmemAddressableBits(addressing_bits);2311}2312} else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {2313uint32_t reg = UINT32_MAX;2314if (!key.getAsInteger(16, reg))2315expedited_register_map[reg] = std::string(std::move(value));2316}2317}23182319if (stop_pid != LLDB_INVALID_PROCESS_ID && stop_pid != pid) {2320Log *log = GetLog(GDBRLog::Process);2321LLDB_LOG(log,2322"Received stop for incorrect PID = {0} (inferior PID = {1})",2323stop_pid, pid);2324return eStateInvalid;2325}23262327if (tid == LLDB_INVALID_THREAD_ID) {2328// A thread id may be invalid if the response is old style 'S' packet2329// which does not provide the2330// thread information. So update the thread list and choose the first2331// one.2332UpdateThreadIDList();23332334if (!m_thread_ids.empty()) {2335tid = m_thread_ids.front();2336}2337}23382339SetAddressableBitMasks(addressable_bits);23402341ThreadSP thread_sp = SetThreadStopInfo(2342tid, expedited_register_map, signo, thread_name, reason, description,2343exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,2344associated_with_dispatch_queue, dispatch_queue_t, queue_name,2345queue_kind, queue_serial_number);23462347return eStateStopped;2348} break;23492350case 'W':2351case 'X':2352// process exited2353return eStateExited;23542355default:2356break;2357}2358return eStateInvalid;2359}23602361void ProcessGDBRemote::RefreshStateAfterStop() {2362std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());23632364m_thread_ids.clear();2365m_thread_pcs.clear();23662367// Set the thread stop info. It might have a "threads" key whose value is a2368// list of all thread IDs in the current process, so m_thread_ids might get2369// set.2370// Check to see if SetThreadStopInfo() filled in m_thread_ids?2371if (m_thread_ids.empty()) {2372// No, we need to fetch the thread list manually2373UpdateThreadIDList();2374}23752376// We might set some stop info's so make sure the thread list is up to2377// date before we do that or we might overwrite what was computed here.2378UpdateThreadListIfNeeded();23792380if (m_last_stop_packet)2381SetThreadStopInfo(*m_last_stop_packet);2382m_last_stop_packet.reset();23832384// If we have queried for a default thread id2385if (m_initial_tid != LLDB_INVALID_THREAD_ID) {2386m_thread_list.SetSelectedThreadByID(m_initial_tid);2387m_initial_tid = LLDB_INVALID_THREAD_ID;2388}23892390// Let all threads recover from stopping and do any clean up based on the2391// previous thread state (if any).2392m_thread_list_real.RefreshStateAfterStop();2393}23942395Status ProcessGDBRemote::DoHalt(bool &caused_stop) {2396Status error;23972398if (m_public_state.GetValue() == eStateAttaching) {2399// We are being asked to halt during an attach. We used to just close our2400// file handle and debugserver will go away, but with remote proxies, it2401// is better to send a positive signal, so let's send the interrupt first...2402caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());2403m_gdb_comm.Disconnect();2404} else2405caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());2406return error;2407}24082409Status ProcessGDBRemote::DoDetach(bool keep_stopped) {2410Status error;2411Log *log = GetLog(GDBRLog::Process);2412LLDB_LOGF(log, "ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);24132414error = m_gdb_comm.Detach(keep_stopped);2415if (log) {2416if (error.Success())2417log->PutCString(2418"ProcessGDBRemote::DoDetach() detach packet sent successfully");2419else2420LLDB_LOGF(log,2421"ProcessGDBRemote::DoDetach() detach packet send failed: %s",2422error.AsCString() ? error.AsCString() : "<unknown error>");2423}24242425if (!error.Success())2426return error;24272428// Sleep for one second to let the process get all detached...2429StopAsyncThread();24302431SetPrivateState(eStateDetached);2432ResumePrivateStateThread();24332434// KillDebugserverProcess ();2435return error;2436}24372438Status ProcessGDBRemote::DoDestroy() {2439Log *log = GetLog(GDBRLog::Process);2440LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy()");24412442// Interrupt if our inferior is running...2443int exit_status = SIGABRT;2444std::string exit_string;24452446if (m_gdb_comm.IsConnected()) {2447if (m_public_state.GetValue() != eStateAttaching) {2448llvm::Expected<int> kill_res = m_gdb_comm.KillProcess(GetID());24492450if (kill_res) {2451exit_status = kill_res.get();2452#if defined(__APPLE__)2453// For Native processes on Mac OS X, we launch through the Host2454// Platform, then hand the process off to debugserver, which becomes2455// the parent process through "PT_ATTACH". Then when we go to kill2456// the process on Mac OS X we call ptrace(PT_KILL) to kill it, then2457// we call waitpid which returns with no error and the correct2458// status. But amusingly enough that doesn't seem to actually reap2459// the process, but instead it is left around as a Zombie. Probably2460// the kernel is in the process of switching ownership back to lldb2461// which was the original parent, and gets confused in the handoff.2462// Anyway, so call waitpid here to finally reap it.2463PlatformSP platform_sp(GetTarget().GetPlatform());2464if (platform_sp && platform_sp->IsHost()) {2465int status;2466::pid_t reap_pid;2467reap_pid = waitpid(GetID(), &status, WNOHANG);2468LLDB_LOGF(log, "Reaped pid: %d, status: %d.\n", reap_pid, status);2469}2470#endif2471ClearThreadIDList();2472exit_string.assign("killed");2473} else {2474exit_string.assign(llvm::toString(kill_res.takeError()));2475}2476} else {2477exit_string.assign("killed or interrupted while attaching.");2478}2479} else {2480// If we missed setting the exit status on the way out, do it here.2481// NB set exit status can be called multiple times, the first one sets the2482// status.2483exit_string.assign("destroying when not connected to debugserver");2484}24852486SetExitStatus(exit_status, exit_string.c_str());24872488StopAsyncThread();2489KillDebugserverProcess();2490return Status();2491}24922493void ProcessGDBRemote::SetLastStopPacket(2494const StringExtractorGDBRemote &response) {2495const bool did_exec =2496response.GetStringRef().find(";reason:exec;") != std::string::npos;2497if (did_exec) {2498Log *log = GetLog(GDBRLog::Process);2499LLDB_LOGF(log, "ProcessGDBRemote::SetLastStopPacket () - detected exec");25002501m_thread_list_real.Clear();2502m_thread_list.Clear();2503BuildDynamicRegisterInfo(true);2504m_gdb_comm.ResetDiscoverableSettings(did_exec);2505}25062507m_last_stop_packet = response;2508}25092510void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) {2511Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));2512}25132514// Process Queries25152516bool ProcessGDBRemote::IsAlive() {2517return m_gdb_comm.IsConnected() && Process::IsAlive();2518}25192520addr_t ProcessGDBRemote::GetImageInfoAddress() {2521// request the link map address via the $qShlibInfoAddr packet2522lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();25232524// the loaded module list can also provides a link map address2525if (addr == LLDB_INVALID_ADDRESS) {2526llvm::Expected<LoadedModuleInfoList> list = GetLoadedModuleList();2527if (!list) {2528Log *log = GetLog(GDBRLog::Process);2529LLDB_LOG_ERROR(log, list.takeError(), "Failed to read module list: {0}.");2530} else {2531addr = list->m_link_map;2532}2533}25342535return addr;2536}25372538void ProcessGDBRemote::WillPublicStop() {2539// See if the GDB remote client supports the JSON threads info. If so, we2540// gather stop info for all threads, expedited registers, expedited memory,2541// runtime queue information (iOS and MacOSX only), and more. Expediting2542// memory will help stack backtracing be much faster. Expediting registers2543// will make sure we don't have to read the thread registers for GPRs.2544m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();25452546if (m_jthreadsinfo_sp) {2547// Now set the stop info for each thread and also expedite any registers2548// and memory that was in the jThreadsInfo response.2549StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();2550if (thread_infos) {2551const size_t n = thread_infos->GetSize();2552for (size_t i = 0; i < n; ++i) {2553StructuredData::Dictionary *thread_dict =2554thread_infos->GetItemAtIndex(i)->GetAsDictionary();2555if (thread_dict)2556SetThreadStopInfo(thread_dict);2557}2558}2559}2560}25612562// Process Memory2563size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,2564Status &error) {2565GetMaxMemorySize();2566bool binary_memory_read = m_gdb_comm.GetxPacketSupported();2567// M and m packets take 2 bytes for 1 byte of memory2568size_t max_memory_size =2569binary_memory_read ? m_max_memory_size : m_max_memory_size / 2;2570if (size > max_memory_size) {2571// Keep memory read sizes down to a sane limit. This function will be2572// called multiple times in order to complete the task by2573// lldb_private::Process so it is ok to do this.2574size = max_memory_size;2575}25762577char packet[64];2578int packet_len;2579packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,2580binary_memory_read ? 'x' : 'm', (uint64_t)addr,2581(uint64_t)size);2582assert(packet_len + 1 < (int)sizeof(packet));2583UNUSED_IF_ASSERT_DISABLED(packet_len);2584StringExtractorGDBRemote response;2585if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response,2586GetInterruptTimeout()) ==2587GDBRemoteCommunication::PacketResult::Success) {2588if (response.IsNormalResponse()) {2589error.Clear();2590if (binary_memory_read) {2591// The lower level GDBRemoteCommunication packet receive layer has2592// already de-quoted any 0x7d character escaping that was present in2593// the packet25942595size_t data_received_size = response.GetBytesLeft();2596if (data_received_size > size) {2597// Don't write past the end of BUF if the remote debug server gave us2598// too much data for some reason.2599data_received_size = size;2600}2601memcpy(buf, response.GetStringRef().data(), data_received_size);2602return data_received_size;2603} else {2604return response.GetHexBytes(2605llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size), '\xdd');2606}2607} else if (response.IsErrorResponse())2608error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);2609else if (response.IsUnsupportedResponse())2610error.SetErrorStringWithFormat(2611"GDB server does not support reading memory");2612else2613error.SetErrorStringWithFormat(2614"unexpected response to GDB server memory read packet '%s': '%s'",2615packet, response.GetStringRef().data());2616} else {2617error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);2618}2619return 0;2620}26212622bool ProcessGDBRemote::SupportsMemoryTagging() {2623return m_gdb_comm.GetMemoryTaggingSupported();2624}26252626llvm::Expected<std::vector<uint8_t>>2627ProcessGDBRemote::DoReadMemoryTags(lldb::addr_t addr, size_t len,2628int32_t type) {2629// By this point ReadMemoryTags has validated that tagging is enabled2630// for this target/process/address.2631DataBufferSP buffer_sp = m_gdb_comm.ReadMemoryTags(addr, len, type);2632if (!buffer_sp) {2633return llvm::createStringError(llvm::inconvertibleErrorCode(),2634"Error reading memory tags from remote");2635}26362637// Return the raw tag data2638llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();2639std::vector<uint8_t> got;2640got.reserve(tag_data.size());2641std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));2642return got;2643}26442645Status ProcessGDBRemote::DoWriteMemoryTags(lldb::addr_t addr, size_t len,2646int32_t type,2647const std::vector<uint8_t> &tags) {2648// By now WriteMemoryTags should have validated that tagging is enabled2649// for this target/process.2650return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);2651}26522653Status ProcessGDBRemote::WriteObjectFile(2654std::vector<ObjectFile::LoadableData> entries) {2655Status error;2656// Sort the entries by address because some writes, like those to flash2657// memory, must happen in order of increasing address.2658std::stable_sort(2659std::begin(entries), std::end(entries),2660[](const ObjectFile::LoadableData a, const ObjectFile::LoadableData b) {2661return a.Dest < b.Dest;2662});2663m_allow_flash_writes = true;2664error = Process::WriteObjectFile(entries);2665if (error.Success())2666error = FlashDone();2667else2668// Even though some of the writing failed, try to send a flash done if some2669// of the writing succeeded so the flash state is reset to normal, but2670// don't stomp on the error status that was set in the write failure since2671// that's the one we want to report back.2672FlashDone();2673m_allow_flash_writes = false;2674return error;2675}26762677bool ProcessGDBRemote::HasErased(FlashRange range) {2678auto size = m_erased_flash_ranges.GetSize();2679for (size_t i = 0; i < size; ++i)2680if (m_erased_flash_ranges.GetEntryAtIndex(i)->Contains(range))2681return true;2682return false;2683}26842685Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) {2686Status status;26872688MemoryRegionInfo region;2689status = GetMemoryRegionInfo(addr, region);2690if (!status.Success())2691return status;26922693// The gdb spec doesn't say if erasures are allowed across multiple regions,2694// but we'll disallow it to be safe and to keep the logic simple by worring2695// about only one region's block size. DoMemoryWrite is this function's2696// primary user, and it can easily keep writes within a single memory region2697if (addr + size > region.GetRange().GetRangeEnd()) {2698status.SetErrorString("Unable to erase flash in multiple regions");2699return status;2700}27012702uint64_t blocksize = region.GetBlocksize();2703if (blocksize == 0) {2704status.SetErrorString("Unable to erase flash because blocksize is 0");2705return status;2706}27072708// Erasures can only be done on block boundary adresses, so round down addr2709// and round up size2710lldb::addr_t block_start_addr = addr - (addr % blocksize);2711size += (addr - block_start_addr);2712if ((size % blocksize) != 0)2713size += (blocksize - size % blocksize);27142715FlashRange range(block_start_addr, size);27162717if (HasErased(range))2718return status;27192720// We haven't erased the entire range, but we may have erased part of it.2721// (e.g., block A is already erased and range starts in A and ends in B). So,2722// adjust range if necessary to exclude already erased blocks.2723if (!m_erased_flash_ranges.IsEmpty()) {2724// Assuming that writes and erasures are done in increasing addr order,2725// because that is a requirement of the vFlashWrite command. Therefore, we2726// only need to look at the last range in the list for overlap.2727const auto &last_range = *m_erased_flash_ranges.Back();2728if (range.GetRangeBase() < last_range.GetRangeEnd()) {2729auto overlap = last_range.GetRangeEnd() - range.GetRangeBase();2730// overlap will be less than range.GetByteSize() or else HasErased()2731// would have been true2732range.SetByteSize(range.GetByteSize() - overlap);2733range.SetRangeBase(range.GetRangeBase() + overlap);2734}2735}27362737StreamString packet;2738packet.Printf("vFlashErase:%" PRIx64 ",%" PRIx64, range.GetRangeBase(),2739(uint64_t)range.GetByteSize());27402741StringExtractorGDBRemote response;2742if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,2743GetInterruptTimeout()) ==2744GDBRemoteCommunication::PacketResult::Success) {2745if (response.IsOKResponse()) {2746m_erased_flash_ranges.Insert(range, true);2747} else {2748if (response.IsErrorResponse())2749status.SetErrorStringWithFormat("flash erase failed for 0x%" PRIx64,2750addr);2751else if (response.IsUnsupportedResponse())2752status.SetErrorStringWithFormat("GDB server does not support flashing");2753else2754status.SetErrorStringWithFormat(2755"unexpected response to GDB server flash erase packet '%s': '%s'",2756packet.GetData(), response.GetStringRef().data());2757}2758} else {2759status.SetErrorStringWithFormat("failed to send packet: '%s'",2760packet.GetData());2761}2762return status;2763}27642765Status ProcessGDBRemote::FlashDone() {2766Status status;2767// If we haven't erased any blocks, then we must not have written anything2768// either, so there is no need to actually send a vFlashDone command2769if (m_erased_flash_ranges.IsEmpty())2770return status;2771StringExtractorGDBRemote response;2772if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response,2773GetInterruptTimeout()) ==2774GDBRemoteCommunication::PacketResult::Success) {2775if (response.IsOKResponse()) {2776m_erased_flash_ranges.Clear();2777} else {2778if (response.IsErrorResponse())2779status.SetErrorStringWithFormat("flash done failed");2780else if (response.IsUnsupportedResponse())2781status.SetErrorStringWithFormat("GDB server does not support flashing");2782else2783status.SetErrorStringWithFormat(2784"unexpected response to GDB server flash done packet: '%s'",2785response.GetStringRef().data());2786}2787} else {2788status.SetErrorStringWithFormat("failed to send flash done packet");2789}2790return status;2791}27922793size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,2794size_t size, Status &error) {2795GetMaxMemorySize();2796// M and m packets take 2 bytes for 1 byte of memory2797size_t max_memory_size = m_max_memory_size / 2;2798if (size > max_memory_size) {2799// Keep memory read sizes down to a sane limit. This function will be2800// called multiple times in order to complete the task by2801// lldb_private::Process so it is ok to do this.2802size = max_memory_size;2803}28042805StreamGDBRemote packet;28062807MemoryRegionInfo region;2808Status region_status = GetMemoryRegionInfo(addr, region);28092810bool is_flash =2811region_status.Success() && region.GetFlash() == MemoryRegionInfo::eYes;28122813if (is_flash) {2814if (!m_allow_flash_writes) {2815error.SetErrorString("Writing to flash memory is not allowed");2816return 0;2817}2818// Keep the write within a flash memory region2819if (addr + size > region.GetRange().GetRangeEnd())2820size = region.GetRange().GetRangeEnd() - addr;2821// Flash memory must be erased before it can be written2822error = FlashErase(addr, size);2823if (!error.Success())2824return 0;2825packet.Printf("vFlashWrite:%" PRIx64 ":", addr);2826packet.PutEscapedBytes(buf, size);2827} else {2828packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);2829packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(),2830endian::InlHostByteOrder());2831}2832StringExtractorGDBRemote response;2833if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,2834GetInterruptTimeout()) ==2835GDBRemoteCommunication::PacketResult::Success) {2836if (response.IsOKResponse()) {2837error.Clear();2838return size;2839} else if (response.IsErrorResponse())2840error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64,2841addr);2842else if (response.IsUnsupportedResponse())2843error.SetErrorStringWithFormat(2844"GDB server does not support writing memory");2845else2846error.SetErrorStringWithFormat(2847"unexpected response to GDB server memory write packet '%s': '%s'",2848packet.GetData(), response.GetStringRef().data());2849} else {2850error.SetErrorStringWithFormat("failed to send packet: '%s'",2851packet.GetData());2852}2853return 0;2854}28552856lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,2857uint32_t permissions,2858Status &error) {2859Log *log = GetLog(LLDBLog::Process | LLDBLog::Expressions);2860addr_t allocated_addr = LLDB_INVALID_ADDRESS;28612862if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo) {2863allocated_addr = m_gdb_comm.AllocateMemory(size, permissions);2864if (allocated_addr != LLDB_INVALID_ADDRESS ||2865m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)2866return allocated_addr;2867}28682869if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo) {2870// Call mmap() to create memory in the inferior..2871unsigned prot = 0;2872if (permissions & lldb::ePermissionsReadable)2873prot |= eMmapProtRead;2874if (permissions & lldb::ePermissionsWritable)2875prot |= eMmapProtWrite;2876if (permissions & lldb::ePermissionsExecutable)2877prot |= eMmapProtExec;28782879if (InferiorCallMmap(this, allocated_addr, 0, size, prot,2880eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))2881m_addr_to_mmap_size[allocated_addr] = size;2882else {2883allocated_addr = LLDB_INVALID_ADDRESS;2884LLDB_LOGF(log,2885"ProcessGDBRemote::%s no direct stub support for memory "2886"allocation, and InferiorCallMmap also failed - is stub "2887"missing register context save/restore capability?",2888__FUNCTION__);2889}2890}28912892if (allocated_addr == LLDB_INVALID_ADDRESS)2893error.SetErrorStringWithFormat(2894"unable to allocate %" PRIu64 " bytes of memory with permissions %s",2895(uint64_t)size, GetPermissionsAsCString(permissions));2896else2897error.Clear();2898return allocated_addr;2899}29002901Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr,2902MemoryRegionInfo ®ion_info) {29032904Status error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));2905return error;2906}29072908std::optional<uint32_t> ProcessGDBRemote::GetWatchpointSlotCount() {2909return m_gdb_comm.GetWatchpointSlotCount();2910}29112912std::optional<bool> ProcessGDBRemote::DoGetWatchpointReportedAfter() {2913return m_gdb_comm.GetWatchpointReportedAfter();2914}29152916Status ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) {2917Status error;2918LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();29192920switch (supported) {2921case eLazyBoolCalculate:2922// We should never be deallocating memory without allocating memory first2923// so we should never get eLazyBoolCalculate2924error.SetErrorString(2925"tried to deallocate memory without ever allocating memory");2926break;29272928case eLazyBoolYes:2929if (!m_gdb_comm.DeallocateMemory(addr))2930error.SetErrorStringWithFormat(2931"unable to deallocate memory at 0x%" PRIx64, addr);2932break;29332934case eLazyBoolNo:2935// Call munmap() to deallocate memory in the inferior..2936{2937MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);2938if (pos != m_addr_to_mmap_size.end() &&2939InferiorCallMunmap(this, addr, pos->second))2940m_addr_to_mmap_size.erase(pos);2941else2942error.SetErrorStringWithFormat(2943"unable to deallocate memory at 0x%" PRIx64, addr);2944}2945break;2946}29472948return error;2949}29502951// Process STDIO2952size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,2953Status &error) {2954if (m_stdio_communication.IsConnected()) {2955ConnectionStatus status;2956m_stdio_communication.WriteAll(src, src_len, status, nullptr);2957} else if (m_stdin_forward) {2958m_gdb_comm.SendStdinNotification(src, src_len);2959}2960return 0;2961}29622963Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {2964Status error;2965assert(bp_site != nullptr);29662967// Get logging info2968Log *log = GetLog(GDBRLog::Breakpoints);2969user_id_t site_id = bp_site->GetID();29702971// Get the breakpoint address2972const addr_t addr = bp_site->GetLoadAddress();29732974// Log that a breakpoint was requested2975LLDB_LOGF(log,2976"ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu642977") address = 0x%" PRIx64,2978site_id, (uint64_t)addr);29792980// Breakpoint already exists and is enabled2981if (bp_site->IsEnabled()) {2982LLDB_LOGF(log,2983"ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu642984") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",2985site_id, (uint64_t)addr);2986return error;2987}29882989// Get the software breakpoint trap opcode size2990const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);29912992// SupportsGDBStoppointPacket() simply checks a boolean, indicating if this2993// breakpoint type is supported by the remote stub. These are set to true by2994// default, and later set to false only after we receive an unimplemented2995// response when sending a breakpoint packet. This means initially that2996// unless we were specifically instructed to use a hardware breakpoint, LLDB2997// will attempt to set a software breakpoint. HardwareRequired() also queries2998// a boolean variable which indicates if the user specifically asked for2999// hardware breakpoints. If true then we will skip over software3000// breakpoints.3001if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) &&3002(!bp_site->HardwareRequired())) {3003// Try to send off a software breakpoint packet ($Z0)3004uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(3005eBreakpointSoftware, true, addr, bp_op_size, GetInterruptTimeout());3006if (error_no == 0) {3007// The breakpoint was placed successfully3008bp_site->SetEnabled(true);3009bp_site->SetType(BreakpointSite::eExternal);3010return error;3011}30123013// SendGDBStoppointTypePacket() will return an error if it was unable to3014// set this breakpoint. We need to differentiate between a error specific3015// to placing this breakpoint or if we have learned that this breakpoint3016// type is unsupported. To do this, we must test the support boolean for3017// this breakpoint type to see if it now indicates that this breakpoint3018// type is unsupported. If they are still supported then we should return3019// with the error code. If they are now unsupported, then we would like to3020// fall through and try another form of breakpoint.3021if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {3022if (error_no != UINT8_MAX)3023error.SetErrorStringWithFormat(3024"error: %d sending the breakpoint request", error_no);3025else3026error.SetErrorString("error sending the breakpoint request");3027return error;3028}30293030// We reach here when software breakpoints have been found to be3031// unsupported. For future calls to set a breakpoint, we will not attempt3032// to set a breakpoint with a type that is known not to be supported.3033LLDB_LOGF(log, "Software breakpoints are unsupported");30343035// So we will fall through and try a hardware breakpoint3036}30373038// The process of setting a hardware breakpoint is much the same as above.3039// We check the supported boolean for this breakpoint type, and if it is3040// thought to be supported then we will try to set this breakpoint with a3041// hardware breakpoint.3042if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {3043// Try to send off a hardware breakpoint packet ($Z1)3044uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(3045eBreakpointHardware, true, addr, bp_op_size, GetInterruptTimeout());3046if (error_no == 0) {3047// The breakpoint was placed successfully3048bp_site->SetEnabled(true);3049bp_site->SetType(BreakpointSite::eHardware);3050return error;3051}30523053// Check if the error was something other then an unsupported breakpoint3054// type3055if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {3056// Unable to set this hardware breakpoint3057if (error_no != UINT8_MAX)3058error.SetErrorStringWithFormat(3059"error: %d sending the hardware breakpoint request "3060"(hardware breakpoint resources might be exhausted or unavailable)",3061error_no);3062else3063error.SetErrorString("error sending the hardware breakpoint request "3064"(hardware breakpoint resources "3065"might be exhausted or unavailable)");3066return error;3067}30683069// We will reach here when the stub gives an unsupported response to a3070// hardware breakpoint3071LLDB_LOGF(log, "Hardware breakpoints are unsupported");30723073// Finally we will falling through to a #trap style breakpoint3074}30753076// Don't fall through when hardware breakpoints were specifically requested3077if (bp_site->HardwareRequired()) {3078error.SetErrorString("hardware breakpoints are not supported");3079return error;3080}30813082// As a last resort we want to place a manual breakpoint. An instruction is3083// placed into the process memory using memory write packets.3084return EnableSoftwareBreakpoint(bp_site);3085}30863087Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {3088Status error;3089assert(bp_site != nullptr);3090addr_t addr = bp_site->GetLoadAddress();3091user_id_t site_id = bp_site->GetID();3092Log *log = GetLog(GDBRLog::Breakpoints);3093LLDB_LOGF(log,3094"ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu643095") addr = 0x%8.8" PRIx64,3096site_id, (uint64_t)addr);30973098if (bp_site->IsEnabled()) {3099const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);31003101BreakpointSite::Type bp_type = bp_site->GetType();3102switch (bp_type) {3103case BreakpointSite::eSoftware:3104error = DisableSoftwareBreakpoint(bp_site);3105break;31063107case BreakpointSite::eHardware:3108if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,3109addr, bp_op_size,3110GetInterruptTimeout()))3111error.SetErrorToGenericError();3112break;31133114case BreakpointSite::eExternal: {3115if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false,3116addr, bp_op_size,3117GetInterruptTimeout()))3118error.SetErrorToGenericError();3119} break;3120}3121if (error.Success())3122bp_site->SetEnabled(false);3123} else {3124LLDB_LOGF(log,3125"ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu643126") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",3127site_id, (uint64_t)addr);3128return error;3129}31303131if (error.Success())3132error.SetErrorToGenericError();3133return error;3134}31353136// Pre-requisite: wp != NULL.3137static GDBStoppointType3138GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp) {3139assert(wp_res_sp);3140bool read = wp_res_sp->WatchpointResourceRead();3141bool write = wp_res_sp->WatchpointResourceWrite();31423143assert((read || write) &&3144"WatchpointResource type is neither read nor write");3145if (read && write)3146return eWatchpointReadWrite;3147else if (read)3148return eWatchpointRead;3149else3150return eWatchpointWrite;3151}31523153Status ProcessGDBRemote::EnableWatchpoint(WatchpointSP wp_sp, bool notify) {3154Status error;3155if (!wp_sp) {3156error.SetErrorString("No watchpoint specified");3157return error;3158}3159user_id_t watchID = wp_sp->GetID();3160addr_t addr = wp_sp->GetLoadAddress();3161Log *log(GetLog(GDBRLog::Watchpoints));3162LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",3163watchID);3164if (wp_sp->IsEnabled()) {3165LLDB_LOGF(log,3166"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu643167") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",3168watchID, (uint64_t)addr);3169return error;3170}31713172bool read = wp_sp->WatchpointRead();3173bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();3174size_t size = wp_sp->GetByteSize();31753176ArchSpec target_arch = GetTarget().GetArchitecture();3177WatchpointHardwareFeature supported_features =3178m_gdb_comm.GetSupportedWatchpointTypes();31793180std::vector<WatchpointResourceSP> resources =3181WatchpointAlgorithms::AtomizeWatchpointRequest(3182addr, size, read, write, supported_features, target_arch);31833184// LWP_TODO: Now that we know the WP Resources needed to implement this3185// Watchpoint, we need to look at currently allocated Resources in the3186// Process and if they match, or are within the same memory granule, or3187// overlapping memory ranges, then we need to combine them. e.g. one3188// Watchpoint watching 1 byte at 0x1002 and a second watchpoint watching 13189// byte at 0x1003, they must use the same hardware watchpoint register3190// (Resource) to watch them.31913192// This may mean that an existing resource changes its type (read to3193// read+write) or address range it is watching, in which case the old3194// watchpoint needs to be disabled and the new Resource addr/size/type3195// watchpoint enabled.31963197// If we modify a shared Resource to accomodate this newly added Watchpoint,3198// and we are unable to set all of the Resources for it in the inferior, we3199// will return an error for this Watchpoint and the shared Resource should3200// be restored. e.g. this Watchpoint requires three Resources, one which3201// is shared with another Watchpoint. We extend the shared Resouce to3202// handle both Watchpoints and we try to set two new ones. But if we don't3203// have sufficient watchpoint register for all 3, we need to show an error3204// for creating this Watchpoint and we should reset the shared Resource to3205// its original configuration because it is no longer shared.32063207bool set_all_resources = true;3208std::vector<WatchpointResourceSP> succesfully_set_resources;3209for (const auto &wp_res_sp : resources) {3210addr_t addr = wp_res_sp->GetLoadAddress();3211size_t size = wp_res_sp->GetByteSize();3212GDBStoppointType type = GetGDBStoppointType(wp_res_sp);3213if (!m_gdb_comm.SupportsGDBStoppointPacket(type) ||3214m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, size,3215GetInterruptTimeout())) {3216set_all_resources = false;3217break;3218} else {3219succesfully_set_resources.push_back(wp_res_sp);3220}3221}3222if (set_all_resources) {3223wp_sp->SetEnabled(true, notify);3224for (const auto &wp_res_sp : resources) {3225// LWP_TODO: If we expanded/reused an existing Resource,3226// it's already in the WatchpointResourceList.3227wp_res_sp->AddConstituent(wp_sp);3228m_watchpoint_resource_list.Add(wp_res_sp);3229}3230return error;3231} else {3232// We failed to allocate one of the resources. Unset all3233// of the new resources we did successfully set in the3234// process.3235for (const auto &wp_res_sp : succesfully_set_resources) {3236addr_t addr = wp_res_sp->GetLoadAddress();3237size_t size = wp_res_sp->GetByteSize();3238GDBStoppointType type = GetGDBStoppointType(wp_res_sp);3239m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, size,3240GetInterruptTimeout());3241}3242error.SetErrorString("Setting one of the watchpoint resources failed");3243}3244return error;3245}32463247Status ProcessGDBRemote::DisableWatchpoint(WatchpointSP wp_sp, bool notify) {3248Status error;3249if (!wp_sp) {3250error.SetErrorString("Watchpoint argument was NULL.");3251return error;3252}32533254user_id_t watchID = wp_sp->GetID();32553256Log *log(GetLog(GDBRLog::Watchpoints));32573258addr_t addr = wp_sp->GetLoadAddress();32593260LLDB_LOGF(log,3261"ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu643262") addr = 0x%8.8" PRIx64,3263watchID, (uint64_t)addr);32643265if (!wp_sp->IsEnabled()) {3266LLDB_LOGF(log,3267"ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu643268") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",3269watchID, (uint64_t)addr);3270// See also 'class WatchpointSentry' within StopInfo.cpp. This disabling3271// attempt might come from the user-supplied actions, we'll route it in3272// order for the watchpoint object to intelligently process this action.3273wp_sp->SetEnabled(false, notify);3274return error;3275}32763277if (wp_sp->IsHardware()) {3278bool disabled_all = true;32793280std::vector<WatchpointResourceSP> unused_resources;3281for (const auto &wp_res_sp : m_watchpoint_resource_list.Sites()) {3282if (wp_res_sp->ConstituentsContains(wp_sp)) {3283GDBStoppointType type = GetGDBStoppointType(wp_res_sp);3284addr_t addr = wp_res_sp->GetLoadAddress();3285size_t size = wp_res_sp->GetByteSize();3286if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, size,3287GetInterruptTimeout())) {3288disabled_all = false;3289} else {3290wp_res_sp->RemoveConstituent(wp_sp);3291if (wp_res_sp->GetNumberOfConstituents() == 0)3292unused_resources.push_back(wp_res_sp);3293}3294}3295}3296for (auto &wp_res_sp : unused_resources)3297m_watchpoint_resource_list.Remove(wp_res_sp->GetID());32983299wp_sp->SetEnabled(false, notify);3300if (!disabled_all)3301error.SetErrorString("Failure disabling one of the watchpoint locations");3302}3303return error;3304}33053306void ProcessGDBRemote::Clear() {3307m_thread_list_real.Clear();3308m_thread_list.Clear();3309}33103311Status ProcessGDBRemote::DoSignal(int signo) {3312Status error;3313Log *log = GetLog(GDBRLog::Process);3314LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo);33153316if (!m_gdb_comm.SendAsyncSignal(signo, GetInterruptTimeout()))3317error.SetErrorStringWithFormat("failed to send signal %i", signo);3318return error;3319}33203321Status3322ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {3323// Make sure we aren't already connected?3324if (m_gdb_comm.IsConnected())3325return Status();33263327PlatformSP platform_sp(GetTarget().GetPlatform());3328if (platform_sp && !platform_sp->IsHost())3329return Status("Lost debug server connection");33303331auto error = LaunchAndConnectToDebugserver(process_info);3332if (error.Fail()) {3333const char *error_string = error.AsCString();3334if (error_string == nullptr)3335error_string = "unable to launch " DEBUGSERVER_BASENAME;3336}3337return error;3338}3339#if !defined(_WIN32)3340#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 13341#endif33423343#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION3344static bool SetCloexecFlag(int fd) {3345#if defined(FD_CLOEXEC)3346int flags = ::fcntl(fd, F_GETFD);3347if (flags == -1)3348return false;3349return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);3350#else3351return false;3352#endif3353}3354#endif33553356Status ProcessGDBRemote::LaunchAndConnectToDebugserver(3357const ProcessInfo &process_info) {3358using namespace std::placeholders; // For _1, _2, etc.33593360Status error;3361if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) {3362// If we locate debugserver, keep that located version around3363static FileSpec g_debugserver_file_spec;33643365ProcessLaunchInfo debugserver_launch_info;3366// Make debugserver run in its own session so signals generated by special3367// terminal key sequences (^C) don't affect debugserver.3368debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);33693370const std::weak_ptr<ProcessGDBRemote> this_wp =3371std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());3372debugserver_launch_info.SetMonitorProcessCallback(3373std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3));3374debugserver_launch_info.SetUserID(process_info.GetUserID());33753376#if defined(__APPLE__)3377// On macOS 11, we need to support x86_64 applications translated to3378// arm64. We check whether a binary is translated and spawn the correct3379// debugserver accordingly.3380int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,3381static_cast<int>(process_info.GetProcessID()) };3382struct kinfo_proc processInfo;3383size_t bufsize = sizeof(processInfo);3384if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo,3385&bufsize, NULL, 0) == 0 && bufsize > 0) {3386if (processInfo.kp_proc.p_flag & P_TRANSLATED) {3387FileSpec rosetta_debugserver("/Library/Apple/usr/libexec/oah/debugserver");3388debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false);3389}3390}3391#endif33923393int communication_fd = -1;3394#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION3395// Use a socketpair on non-Windows systems for security and performance3396// reasons.3397int sockets[2]; /* the pair of socket descriptors */3398if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {3399error.SetErrorToErrno();3400return error;3401}34023403int our_socket = sockets[0];3404int gdb_socket = sockets[1];3405auto cleanup_our = llvm::make_scope_exit([&]() { close(our_socket); });3406auto cleanup_gdb = llvm::make_scope_exit([&]() { close(gdb_socket); });34073408// Don't let any child processes inherit our communication socket3409SetCloexecFlag(our_socket);3410communication_fd = gdb_socket;3411#endif34123413error = m_gdb_comm.StartDebugserverProcess(3414nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info,3415nullptr, nullptr, communication_fd);34163417if (error.Success())3418m_debugserver_pid = debugserver_launch_info.GetProcessID();3419else3420m_debugserver_pid = LLDB_INVALID_PROCESS_ID;34213422if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {3423#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION3424// Our process spawned correctly, we can now set our connection to use3425// our end of the socket pair3426cleanup_our.release();3427m_gdb_comm.SetConnection(3428std::make_unique<ConnectionFileDescriptor>(our_socket, true));3429#endif3430StartAsyncThread();3431}34323433if (error.Fail()) {3434Log *log = GetLog(GDBRLog::Process);34353436LLDB_LOGF(log, "failed to start debugserver process: %s",3437error.AsCString());3438return error;3439}34403441if (m_gdb_comm.IsConnected()) {3442// Finish the connection process by doing the handshake without3443// connecting (send NULL URL)3444error = ConnectToDebugserver("");3445} else {3446error.SetErrorString("connection failed");3447}3448}3449return error;3450}34513452void ProcessGDBRemote::MonitorDebugserverProcess(3453std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,3454int signo, // Zero for no signal3455int exit_status // Exit value of process if signal is zero3456) {3457// "debugserver_pid" argument passed in is the process ID for debugserver3458// that we are tracking...3459Log *log = GetLog(GDBRLog::Process);34603461LLDB_LOGF(log,3462"ProcessGDBRemote::%s(process_wp, pid=%" PRIu643463", signo=%i (0x%x), exit_status=%i)",3464__FUNCTION__, debugserver_pid, signo, signo, exit_status);34653466std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();3467LLDB_LOGF(log, "ProcessGDBRemote::%s(process = %p)", __FUNCTION__,3468static_cast<void *>(process_sp.get()));3469if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)3470return;34713472// Sleep for a half a second to make sure our inferior process has time to3473// set its exit status before we set it incorrectly when both the debugserver3474// and the inferior process shut down.3475std::this_thread::sleep_for(std::chrono::milliseconds(500));34763477// If our process hasn't yet exited, debugserver might have died. If the3478// process did exit, then we are reaping it.3479const StateType state = process_sp->GetState();34803481if (state != eStateInvalid && state != eStateUnloaded &&3482state != eStateExited && state != eStateDetached) {3483StreamString stream;3484if (signo == 0)3485stream.Format(DEBUGSERVER_BASENAME " died with an exit status of {0:x8}",3486exit_status);3487else {3488llvm::StringRef signal_name =3489process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);3490const char *format_str = DEBUGSERVER_BASENAME " died with signal {0}";3491if (!signal_name.empty())3492stream.Format(format_str, signal_name);3493else3494stream.Format(format_str, signo);3495}3496process_sp->SetExitStatus(-1, stream.GetString());3497}3498// Debugserver has exited we need to let our ProcessGDBRemote know that it no3499// longer has a debugserver instance3500process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;3501}35023503void ProcessGDBRemote::KillDebugserverProcess() {3504m_gdb_comm.Disconnect();3505if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {3506Host::Kill(m_debugserver_pid, SIGINT);3507m_debugserver_pid = LLDB_INVALID_PROCESS_ID;3508}3509}35103511void ProcessGDBRemote::Initialize() {3512static llvm::once_flag g_once_flag;35133514llvm::call_once(g_once_flag, []() {3515PluginManager::RegisterPlugin(GetPluginNameStatic(),3516GetPluginDescriptionStatic(), CreateInstance,3517DebuggerInitialize);3518});3519}35203521void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) {3522if (!PluginManager::GetSettingForProcessPlugin(3523debugger, PluginProperties::GetSettingName())) {3524const bool is_global_setting = true;3525PluginManager::CreateSettingForProcessPlugin(3526debugger, GetGlobalPluginProperties().GetValueProperties(),3527"Properties for the gdb-remote process plug-in.", is_global_setting);3528}3529}35303531bool ProcessGDBRemote::StartAsyncThread() {3532Log *log = GetLog(GDBRLog::Process);35333534LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__);35353536std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);3537if (!m_async_thread.IsJoinable()) {3538// Create a thread that watches our internal state and controls which3539// events make it to clients (into the DCProcess event queue).35403541llvm::Expected<HostThread> async_thread =3542ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", [this] {3543return ProcessGDBRemote::AsyncThread();3544});3545if (!async_thread) {3546LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),3547"failed to launch host thread: {0}");3548return false;3549}3550m_async_thread = *async_thread;3551} else3552LLDB_LOGF(log,3553"ProcessGDBRemote::%s () - Called when Async thread was "3554"already running.",3555__FUNCTION__);35563557return m_async_thread.IsJoinable();3558}35593560void ProcessGDBRemote::StopAsyncThread() {3561Log *log = GetLog(GDBRLog::Process);35623563LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__);35643565std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);3566if (m_async_thread.IsJoinable()) {3567m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);35683569// This will shut down the async thread.3570m_gdb_comm.Disconnect(); // Disconnect from the debug server.35713572// Stop the stdio thread3573m_async_thread.Join(nullptr);3574m_async_thread.Reset();3575} else3576LLDB_LOGF(3577log,3578"ProcessGDBRemote::%s () - Called when Async thread was not running.",3579__FUNCTION__);3580}35813582thread_result_t ProcessGDBRemote::AsyncThread() {3583Log *log = GetLog(GDBRLog::Process);3584LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread starting...",3585__FUNCTION__, GetID());35863587EventSP event_sp;35883589// We need to ignore any packets that come in after we have3590// have decided the process has exited. There are some3591// situations, for instance when we try to interrupt a running3592// process and the interrupt fails, where another packet might3593// get delivered after we've decided to give up on the process.3594// But once we've decided we are done with the process we will3595// not be in a state to do anything useful with new packets.3596// So it is safer to simply ignore any remaining packets by3597// explicitly checking for eStateExited before reentering the3598// fetch loop.35993600bool done = false;3601while (!done && GetPrivateState() != eStateExited) {3602LLDB_LOGF(log,3603"ProcessGDBRemote::%s(pid = %" PRIu643604") listener.WaitForEvent (NULL, event_sp)...",3605__FUNCTION__, GetID());36063607if (m_async_listener_sp->GetEvent(event_sp, std::nullopt)) {3608const uint32_t event_type = event_sp->GetType();3609if (event_sp->BroadcasterIs(&m_async_broadcaster)) {3610LLDB_LOGF(log,3611"ProcessGDBRemote::%s(pid = %" PRIu643612") Got an event of type: %d...",3613__FUNCTION__, GetID(), event_type);36143615switch (event_type) {3616case eBroadcastBitAsyncContinue: {3617const EventDataBytes *continue_packet =3618EventDataBytes::GetEventDataFromEvent(event_sp.get());36193620if (continue_packet) {3621const char *continue_cstr =3622(const char *)continue_packet->GetBytes();3623const size_t continue_cstr_len = continue_packet->GetByteSize();3624LLDB_LOGF(log,3625"ProcessGDBRemote::%s(pid = %" PRIu643626") got eBroadcastBitAsyncContinue: %s",3627__FUNCTION__, GetID(), continue_cstr);36283629if (::strstr(continue_cstr, "vAttach") == nullptr)3630SetPrivateState(eStateRunning);3631StringExtractorGDBRemote response;36323633StateType stop_state =3634GetGDBRemote().SendContinuePacketAndWaitForResponse(3635*this, *GetUnixSignals(),3636llvm::StringRef(continue_cstr, continue_cstr_len),3637GetInterruptTimeout(), response);36383639// We need to immediately clear the thread ID list so we are sure3640// to get a valid list of threads. The thread ID list might be3641// contained within the "response", or the stop reply packet that3642// caused the stop. So clear it now before we give the stop reply3643// packet to the process using the3644// SetLastStopPacket()...3645ClearThreadIDList();36463647switch (stop_state) {3648case eStateStopped:3649case eStateCrashed:3650case eStateSuspended:3651SetLastStopPacket(response);3652SetPrivateState(stop_state);3653break;36543655case eStateExited: {3656SetLastStopPacket(response);3657ClearThreadIDList();3658response.SetFilePos(1);36593660int exit_status = response.GetHexU8();3661std::string desc_string;3662if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';') {3663llvm::StringRef desc_str;3664llvm::StringRef desc_token;3665while (response.GetNameColonValue(desc_token, desc_str)) {3666if (desc_token != "description")3667continue;3668StringExtractor extractor(desc_str);3669extractor.GetHexByteString(desc_string);3670}3671}3672SetExitStatus(exit_status, desc_string.c_str());3673done = true;3674break;3675}3676case eStateInvalid: {3677// Check to see if we were trying to attach and if we got back3678// the "E87" error code from debugserver -- this indicates that3679// the process is not debuggable. Return a slightly more3680// helpful error message about why the attach failed.3681if (::strstr(continue_cstr, "vAttach") != nullptr &&3682response.GetError() == 0x87) {3683SetExitStatus(-1, "cannot attach to process due to "3684"System Integrity Protection");3685} else if (::strstr(continue_cstr, "vAttach") != nullptr &&3686response.GetStatus().Fail()) {3687SetExitStatus(-1, response.GetStatus().AsCString());3688} else {3689SetExitStatus(-1, "lost connection");3690}3691done = true;3692break;3693}36943695default:3696SetPrivateState(stop_state);3697break;3698} // switch(stop_state)3699} // if (continue_packet)3700} // case eBroadcastBitAsyncContinue3701break;37023703case eBroadcastBitAsyncThreadShouldExit:3704LLDB_LOGF(log,3705"ProcessGDBRemote::%s(pid = %" PRIu643706") got eBroadcastBitAsyncThreadShouldExit...",3707__FUNCTION__, GetID());3708done = true;3709break;37103711default:3712LLDB_LOGF(log,3713"ProcessGDBRemote::%s(pid = %" PRIu643714") got unknown event 0x%8.8x",3715__FUNCTION__, GetID(), event_type);3716done = true;3717break;3718}3719}3720} else {3721LLDB_LOGF(log,3722"ProcessGDBRemote::%s(pid = %" PRIu643723") listener.WaitForEvent (NULL, event_sp) => false",3724__FUNCTION__, GetID());3725done = true;3726}3727}37283729LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread exiting...",3730__FUNCTION__, GetID());37313732return {};3733}37343735// uint32_t3736// ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList3737// &matches, std::vector<lldb::pid_t> &pids)3738//{3739// // If we are planning to launch the debugserver remotely, then we need to3740// fire up a debugserver3741// // process and ask it for the list of processes. But if we are local, we3742// can let the Host do it.3743// if (m_local_debugserver)3744// {3745// return Host::ListProcessesMatchingName (name, matches, pids);3746// }3747// else3748// {3749// // FIXME: Implement talking to the remote debugserver.3750// return 0;3751// }3752//3753//}3754//3755bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(3756void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,3757lldb::user_id_t break_loc_id) {3758// I don't think I have to do anything here, just make sure I notice the new3759// thread when it starts to3760// run so I can stop it if that's what I want to do.3761Log *log = GetLog(LLDBLog::Step);3762LLDB_LOGF(log, "Hit New Thread Notification breakpoint.");3763return false;3764}37653766Status ProcessGDBRemote::UpdateAutomaticSignalFiltering() {3767Log *log = GetLog(GDBRLog::Process);3768LLDB_LOG(log, "Check if need to update ignored signals");37693770// QPassSignals package is not supported by the server, there is no way we3771// can ignore any signals on server side.3772if (!m_gdb_comm.GetQPassSignalsSupported())3773return Status();37743775// No signals, nothing to send.3776if (m_unix_signals_sp == nullptr)3777return Status();37783779// Signals' version hasn't changed, no need to send anything.3780uint64_t new_signals_version = m_unix_signals_sp->GetVersion();3781if (new_signals_version == m_last_signals_version) {3782LLDB_LOG(log, "Signals' version hasn't changed. version={0}",3783m_last_signals_version);3784return Status();3785}37863787auto signals_to_ignore =3788m_unix_signals_sp->GetFilteredSignals(false, false, false);3789Status error = m_gdb_comm.SendSignalsToIgnore(signals_to_ignore);37903791LLDB_LOG(log,3792"Signals' version changed. old version={0}, new version={1}, "3793"signals ignored={2}, update result={3}",3794m_last_signals_version, new_signals_version,3795signals_to_ignore.size(), error);37963797if (error.Success())3798m_last_signals_version = new_signals_version;37993800return error;3801}38023803bool ProcessGDBRemote::StartNoticingNewThreads() {3804Log *log = GetLog(LLDBLog::Step);3805if (m_thread_create_bp_sp) {3806if (log && log->GetVerbose())3807LLDB_LOGF(log, "Enabled noticing new thread breakpoint.");3808m_thread_create_bp_sp->SetEnabled(true);3809} else {3810PlatformSP platform_sp(GetTarget().GetPlatform());3811if (platform_sp) {3812m_thread_create_bp_sp =3813platform_sp->SetThreadCreationBreakpoint(GetTarget());3814if (m_thread_create_bp_sp) {3815if (log && log->GetVerbose())3816LLDB_LOGF(3817log, "Successfully created new thread notification breakpoint %i",3818m_thread_create_bp_sp->GetID());3819m_thread_create_bp_sp->SetCallback(3820ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);3821} else {3822LLDB_LOGF(log, "Failed to create new thread notification breakpoint.");3823}3824}3825}3826return m_thread_create_bp_sp.get() != nullptr;3827}38283829bool ProcessGDBRemote::StopNoticingNewThreads() {3830Log *log = GetLog(LLDBLog::Step);3831if (log && log->GetVerbose())3832LLDB_LOGF(log, "Disabling new thread notification breakpoint.");38333834if (m_thread_create_bp_sp)3835m_thread_create_bp_sp->SetEnabled(false);38363837return true;3838}38393840DynamicLoader *ProcessGDBRemote::GetDynamicLoader() {3841if (m_dyld_up.get() == nullptr)3842m_dyld_up.reset(DynamicLoader::FindPlugin(this, ""));3843return m_dyld_up.get();3844}38453846Status ProcessGDBRemote::SendEventData(const char *data) {3847int return_value;3848bool was_supported;38493850Status error;38513852return_value = m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);3853if (return_value != 0) {3854if (!was_supported)3855error.SetErrorString("Sending events is not supported for this process.");3856else3857error.SetErrorStringWithFormat("Error sending event data: %d.",3858return_value);3859}3860return error;3861}38623863DataExtractor ProcessGDBRemote::GetAuxvData() {3864DataBufferSP buf;3865if (m_gdb_comm.GetQXferAuxvReadSupported()) {3866llvm::Expected<std::string> response = m_gdb_comm.ReadExtFeature("auxv", "");3867if (response)3868buf = std::make_shared<DataBufferHeap>(response->c_str(),3869response->length());3870else3871LLDB_LOG_ERROR(GetLog(GDBRLog::Process), response.takeError(), "{0}");3872}3873return DataExtractor(buf, GetByteOrder(), GetAddressByteSize());3874}38753876StructuredData::ObjectSP3877ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {3878StructuredData::ObjectSP object_sp;38793880if (m_gdb_comm.GetThreadExtendedInfoSupported()) {3881StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());3882SystemRuntime *runtime = GetSystemRuntime();3883if (runtime) {3884runtime->AddThreadExtendedInfoPacketHints(args_dict);3885}3886args_dict->GetAsDictionary()->AddIntegerItem("thread", tid);38873888StreamString packet;3889packet << "jThreadExtendedInfo:";3890args_dict->Dump(packet, false);38913892// FIXME the final character of a JSON dictionary, '}', is the escape3893// character in gdb-remote binary mode. lldb currently doesn't escape3894// these characters in its packet output -- so we add the quoted version of3895// the } character here manually in case we talk to a debugserver which un-3896// escapes the characters at packet read time.3897packet << (char)(0x7d ^ 0x20);38983899StringExtractorGDBRemote response;3900response.SetResponseValidatorToJSON();3901if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==3902GDBRemoteCommunication::PacketResult::Success) {3903StringExtractorGDBRemote::ResponseType response_type =3904response.GetResponseType();3905if (response_type == StringExtractorGDBRemote::eResponse) {3906if (!response.Empty()) {3907object_sp = StructuredData::ParseJSON(response.GetStringRef());3908}3909}3910}3911}3912return object_sp;3913}39143915StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(3916lldb::addr_t image_list_address, lldb::addr_t image_count) {39173918StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());3919args_dict->GetAsDictionary()->AddIntegerItem("image_list_address",3920image_list_address);3921args_dict->GetAsDictionary()->AddIntegerItem("image_count", image_count);39223923return GetLoadedDynamicLibrariesInfos_sender(args_dict);3924}39253926StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos() {3927StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());39283929args_dict->GetAsDictionary()->AddBooleanItem("fetch_all_solibs", true);39303931return GetLoadedDynamicLibrariesInfos_sender(args_dict);3932}39333934StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(3935const std::vector<lldb::addr_t> &load_addresses) {3936StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());3937StructuredData::ArraySP addresses(new StructuredData::Array);39383939for (auto addr : load_addresses)3940addresses->AddIntegerItem(addr);39413942args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses);39433944return GetLoadedDynamicLibrariesInfos_sender(args_dict);3945}39463947StructuredData::ObjectSP3948ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(3949StructuredData::ObjectSP args_dict) {3950StructuredData::ObjectSP object_sp;39513952if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {3953// Scope for the scoped timeout object3954GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm,3955std::chrono::seconds(10));39563957StreamString packet;3958packet << "jGetLoadedDynamicLibrariesInfos:";3959args_dict->Dump(packet, false);39603961// FIXME the final character of a JSON dictionary, '}', is the escape3962// character in gdb-remote binary mode. lldb currently doesn't escape3963// these characters in its packet output -- so we add the quoted version of3964// the } character here manually in case we talk to a debugserver which un-3965// escapes the characters at packet read time.3966packet << (char)(0x7d ^ 0x20);39673968StringExtractorGDBRemote response;3969response.SetResponseValidatorToJSON();3970if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==3971GDBRemoteCommunication::PacketResult::Success) {3972StringExtractorGDBRemote::ResponseType response_type =3973response.GetResponseType();3974if (response_type == StringExtractorGDBRemote::eResponse) {3975if (!response.Empty()) {3976object_sp = StructuredData::ParseJSON(response.GetStringRef());3977}3978}3979}3980}3981return object_sp;3982}39833984StructuredData::ObjectSP ProcessGDBRemote::GetDynamicLoaderProcessState() {3985StructuredData::ObjectSP object_sp;3986StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());39873988if (m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {3989StringExtractorGDBRemote response;3990response.SetResponseValidatorToJSON();3991if (m_gdb_comm.SendPacketAndWaitForResponse("jGetDyldProcessState",3992response) ==3993GDBRemoteCommunication::PacketResult::Success) {3994StringExtractorGDBRemote::ResponseType response_type =3995response.GetResponseType();3996if (response_type == StringExtractorGDBRemote::eResponse) {3997if (!response.Empty()) {3998object_sp = StructuredData::ParseJSON(response.GetStringRef());3999}4000}4001}4002}4003return object_sp;4004}40054006StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {4007StructuredData::ObjectSP object_sp;4008StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());40094010if (m_gdb_comm.GetSharedCacheInfoSupported()) {4011StreamString packet;4012packet << "jGetSharedCacheInfo:";4013args_dict->Dump(packet, false);40144015// FIXME the final character of a JSON dictionary, '}', is the escape4016// character in gdb-remote binary mode. lldb currently doesn't escape4017// these characters in its packet output -- so we add the quoted version of4018// the } character here manually in case we talk to a debugserver which un-4019// escapes the characters at packet read time.4020packet << (char)(0x7d ^ 0x20);40214022StringExtractorGDBRemote response;4023response.SetResponseValidatorToJSON();4024if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==4025GDBRemoteCommunication::PacketResult::Success) {4026StringExtractorGDBRemote::ResponseType response_type =4027response.GetResponseType();4028if (response_type == StringExtractorGDBRemote::eResponse) {4029if (!response.Empty()) {4030object_sp = StructuredData::ParseJSON(response.GetStringRef());4031}4032}4033}4034}4035return object_sp;4036}40374038Status ProcessGDBRemote::ConfigureStructuredData(4039llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {4040return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);4041}40424043// Establish the largest memory read/write payloads we should use. If the4044// remote stub has a max packet size, stay under that size.4045//4046// If the remote stub's max packet size is crazy large, use a reasonable4047// largeish default.4048//4049// If the remote stub doesn't advertise a max packet size, use a conservative4050// default.40514052void ProcessGDBRemote::GetMaxMemorySize() {4053const uint64_t reasonable_largeish_default = 128 * 1024;4054const uint64_t conservative_default = 512;40554056if (m_max_memory_size == 0) {4057uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();4058if (stub_max_size != UINT64_MAX && stub_max_size != 0) {4059// Save the stub's claimed maximum packet size4060m_remote_stub_max_memory_size = stub_max_size;40614062// Even if the stub says it can support ginormous packets, don't exceed4063// our reasonable largeish default packet size.4064if (stub_max_size > reasonable_largeish_default) {4065stub_max_size = reasonable_largeish_default;4066}40674068// Memory packet have other overheads too like Maddr,size:#NN Instead of4069// calculating the bytes taken by size and addr every time, we take a4070// maximum guess here.4071if (stub_max_size > 70)4072stub_max_size -= 32 + 32 + 6;4073else {4074// In unlikely scenario that max packet size is less then 70, we will4075// hope that data being written is small enough to fit.4076Log *log(GetLog(GDBRLog::Comm | GDBRLog::Memory));4077if (log)4078log->Warning("Packet size is too small. "4079"LLDB may face problems while writing memory");4080}40814082m_max_memory_size = stub_max_size;4083} else {4084m_max_memory_size = conservative_default;4085}4086}4087}40884089void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize(4090uint64_t user_specified_max) {4091if (user_specified_max != 0) {4092GetMaxMemorySize();40934094if (m_remote_stub_max_memory_size != 0) {4095if (m_remote_stub_max_memory_size < user_specified_max) {4096m_max_memory_size = m_remote_stub_max_memory_size; // user specified a4097// packet size too4098// big, go as big4099// as the remote stub says we can go.4100} else {4101m_max_memory_size = user_specified_max; // user's packet size is good4102}4103} else {4104m_max_memory_size =4105user_specified_max; // user's packet size is probably fine4106}4107}4108}41094110bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,4111const ArchSpec &arch,4112ModuleSpec &module_spec) {4113Log *log = GetLog(LLDBLog::Platform);41144115const ModuleCacheKey key(module_file_spec.GetPath(),4116arch.GetTriple().getTriple());4117auto cached = m_cached_module_specs.find(key);4118if (cached != m_cached_module_specs.end()) {4119module_spec = cached->second;4120return bool(module_spec);4121}41224123if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {4124LLDB_LOGF(log, "ProcessGDBRemote::%s - failed to get module info for %s:%s",4125__FUNCTION__, module_file_spec.GetPath().c_str(),4126arch.GetTriple().getTriple().c_str());4127return false;4128}41294130if (log) {4131StreamString stream;4132module_spec.Dump(stream);4133LLDB_LOGF(log, "ProcessGDBRemote::%s - got module info for (%s:%s) : %s",4134__FUNCTION__, module_file_spec.GetPath().c_str(),4135arch.GetTriple().getTriple().c_str(), stream.GetData());4136}41374138m_cached_module_specs[key] = module_spec;4139return true;4140}41414142void ProcessGDBRemote::PrefetchModuleSpecs(4143llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {4144auto module_specs = m_gdb_comm.GetModulesInfo(module_file_specs, triple);4145if (module_specs) {4146for (const FileSpec &spec : module_file_specs)4147m_cached_module_specs[ModuleCacheKey(spec.GetPath(),4148triple.getTriple())] = ModuleSpec();4149for (const ModuleSpec &spec : *module_specs)4150m_cached_module_specs[ModuleCacheKey(spec.GetFileSpec().GetPath(),4151triple.getTriple())] = spec;4152}4153}41544155llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() {4156return m_gdb_comm.GetOSVersion();4157}41584159llvm::VersionTuple ProcessGDBRemote::GetHostMacCatalystVersion() {4160return m_gdb_comm.GetMacCatalystVersion();4161}41624163namespace {41644165typedef std::vector<std::string> stringVec;41664167typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;4168struct RegisterSetInfo {4169ConstString name;4170};41714172typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;41734174struct GdbServerTargetInfo {4175std::string arch;4176std::string osabi;4177stringVec includes;4178RegisterSetMap reg_set_map;4179};41804181static FieldEnum::Enumerators ParseEnumEvalues(const XMLNode &enum_node) {4182Log *log(GetLog(GDBRLog::Process));4183// We will use the last instance of each value. Also we preserve the order4184// of declaration in the XML, as it may not be numerical.4185// For example, hardware may intially release with two states that softwware4186// can read from a register field:4187// 0 = startup, 1 = running4188// If in a future hardware release, the designers added a pre-startup state:4189// 0 = startup, 1 = running, 2 = pre-startup4190// Now it makes more sense to list them in this logical order as opposed to4191// numerical order:4192// 2 = pre-startup, 1 = startup, 0 = startup4193// This only matters for "register info" but let's trust what the server4194// chose regardless.4195std::map<uint64_t, FieldEnum::Enumerator> enumerators;41964197enum_node.ForEachChildElementWithName(4198"evalue", [&enumerators, &log](const XMLNode &enumerator_node) {4199std::optional<llvm::StringRef> name;4200std::optional<uint64_t> value;42014202enumerator_node.ForEachAttribute(4203[&name, &value, &log](const llvm::StringRef &attr_name,4204const llvm::StringRef &attr_value) {4205if (attr_name == "name") {4206if (attr_value.size())4207name = attr_value;4208else4209LLDB_LOG(log, "ProcessGDBRemote::ParseEnumEvalues "4210"Ignoring empty name in evalue");4211} else if (attr_name == "value") {4212uint64_t parsed_value = 0;4213if (llvm::to_integer(attr_value, parsed_value))4214value = parsed_value;4215else4216LLDB_LOG(log,4217"ProcessGDBRemote::ParseEnumEvalues "4218"Invalid value \"{0}\" in "4219"evalue",4220attr_value.data());4221} else4222LLDB_LOG(log,4223"ProcessGDBRemote::ParseEnumEvalues Ignoring "4224"unknown attribute "4225"\"{0}\" in evalue",4226attr_name.data());42274228// Keep walking attributes.4229return true;4230});42314232if (value && name)4233enumerators.insert_or_assign(4234*value, FieldEnum::Enumerator(*value, name->str()));42354236// Find all evalue elements.4237return true;4238});42394240FieldEnum::Enumerators final_enumerators;4241for (auto [_, enumerator] : enumerators)4242final_enumerators.push_back(enumerator);42434244return final_enumerators;4245}42464247static void4248ParseEnums(XMLNode feature_node,4249llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {4250Log *log(GetLog(GDBRLog::Process));42514252// The top level element is "<enum...".4253feature_node.ForEachChildElementWithName(4254"enum", [log, ®isters_enum_types](const XMLNode &enum_node) {4255std::string id;42564257enum_node.ForEachAttribute([&id](const llvm::StringRef &attr_name,4258const llvm::StringRef &attr_value) {4259if (attr_name == "id")4260id = attr_value;42614262// There is also a "size" attribute that is supposed to be the size in4263// bytes of the register this applies to. However:4264// * LLDB doesn't need this information.4265// * It is difficult to verify because you have to wait until the4266// enum is applied to a field.4267//4268// So we will emit this attribute in XML for GDB's sake, but will not4269// bother ingesting it.42704271// Walk all attributes.4272return true;4273});42744275if (!id.empty()) {4276FieldEnum::Enumerators enumerators = ParseEnumEvalues(enum_node);4277if (!enumerators.empty()) {4278LLDB_LOG(log,4279"ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",4280id);4281registers_enum_types.insert_or_assign(4282id, std::make_unique<FieldEnum>(id, enumerators));4283}4284}42854286// Find all <enum> elements.4287return true;4288});4289}42904291static std::vector<RegisterFlags::Field> ParseFlagsFields(4292XMLNode flags_node, unsigned size,4293const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {4294Log *log(GetLog(GDBRLog::Process));4295const unsigned max_start_bit = size * 8 - 1;42964297// Process the fields of this set of flags.4298std::vector<RegisterFlags::Field> fields;4299flags_node.ForEachChildElementWithName("field", [&fields, max_start_bit, &log,4300®isters_enum_types](4301const XMLNode4302&field_node) {4303std::optional<llvm::StringRef> name;4304std::optional<unsigned> start;4305std::optional<unsigned> end;4306std::optional<llvm::StringRef> type;43074308field_node.ForEachAttribute([&name, &start, &end, &type, max_start_bit,4309&log](const llvm::StringRef &attr_name,4310const llvm::StringRef &attr_value) {4311// Note that XML in general requires that each of these attributes only4312// appears once, so we don't have to handle that here.4313if (attr_name == "name") {4314LLDB_LOG(4315log,4316"ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",4317attr_value.data());4318name = attr_value;4319} else if (attr_name == "start") {4320unsigned parsed_start = 0;4321if (llvm::to_integer(attr_value, parsed_start)) {4322if (parsed_start > max_start_bit) {4323LLDB_LOG(log,4324"ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "4325"field node, "4326"cannot be > {1}",4327parsed_start, max_start_bit);4328} else4329start = parsed_start;4330} else {4331LLDB_LOG(4332log,4333"ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "4334"field node",4335attr_value.data());4336}4337} else if (attr_name == "end") {4338unsigned parsed_end = 0;4339if (llvm::to_integer(attr_value, parsed_end))4340if (parsed_end > max_start_bit) {4341LLDB_LOG(log,4342"ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "4343"field node, "4344"cannot be > {1}",4345parsed_end, max_start_bit);4346} else4347end = parsed_end;4348else {4349LLDB_LOG(log,4350"ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "4351"field node",4352attr_value.data());4353}4354} else if (attr_name == "type") {4355type = attr_value;4356} else {4357LLDB_LOG(4358log,4359"ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "4360"\"{0}\" in field node",4361attr_name.data());4362}43634364return true; // Walk all attributes of the field.4365});43664367if (name && start && end) {4368if (*start > *end)4369LLDB_LOG(4370log,4371"ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "4372"\"{2}\", ignoring",4373*start, *end, name->data());4374else {4375if (RegisterFlags::Field::GetSizeInBits(*start, *end) > 64)4376LLDB_LOG(log,4377"ProcessGDBRemote::ParseFlagsFields Ignoring field \"{2}\" "4378"that has "4379"size > 64 bits, this is not supported",4380name->data());4381else {4382// A field's type may be set to the name of an enum type.4383const FieldEnum *enum_type = nullptr;4384if (type && !type->empty()) {4385auto found = registers_enum_types.find(*type);4386if (found != registers_enum_types.end()) {4387enum_type = found->second.get();43884389// No enumerator can exceed the range of the field itself.4390uint64_t max_value =4391RegisterFlags::Field::GetMaxValue(*start, *end);4392for (const auto &enumerator : enum_type->GetEnumerators()) {4393if (enumerator.m_value > max_value) {4394enum_type = nullptr;4395LLDB_LOG(4396log,4397"ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "4398"evalue \"{1}\" with value {2} exceeds the maximum value "4399"of field \"{3}\" ({4}), ignoring enum",4400type->data(), enumerator.m_name, enumerator.m_value,4401name->data(), max_value);4402break;4403}4404}4405} else {4406LLDB_LOG(log,4407"ProcessGDBRemote::ParseFlagsFields Could not find type "4408"\"{0}\" "4409"for field \"{1}\", ignoring",4410type->data(), name->data());4411}4412}44134414fields.push_back(4415RegisterFlags::Field(name->str(), *start, *end, enum_type));4416}4417}4418}44194420return true; // Iterate all "field" nodes.4421});4422return fields;4423}44244425void ParseFlags(4426XMLNode feature_node,4427llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,4428const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {4429Log *log(GetLog(GDBRLog::Process));44304431feature_node.ForEachChildElementWithName(4432"flags",4433[&log, ®isters_flags_types,4434®isters_enum_types](const XMLNode &flags_node) -> bool {4435LLDB_LOG(log, "ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",4436flags_node.GetAttributeValue("id").c_str());44374438std::optional<llvm::StringRef> id;4439std::optional<unsigned> size;4440flags_node.ForEachAttribute(4441[&id, &size, &log](const llvm::StringRef &name,4442const llvm::StringRef &value) {4443if (name == "id") {4444id = value;4445} else if (name == "size") {4446unsigned parsed_size = 0;4447if (llvm::to_integer(value, parsed_size))4448size = parsed_size;4449else {4450LLDB_LOG(log,4451"ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "4452"in flags node",4453value.data());4454}4455} else {4456LLDB_LOG(log,4457"ProcessGDBRemote::ParseFlags Ignoring unknown "4458"attribute \"{0}\" in flags node",4459name.data());4460}4461return true; // Walk all attributes.4462});44634464if (id && size) {4465// Process the fields of this set of flags.4466std::vector<RegisterFlags::Field> fields =4467ParseFlagsFields(flags_node, *size, registers_enum_types);4468if (fields.size()) {4469// Sort so that the fields with the MSBs are first.4470std::sort(fields.rbegin(), fields.rend());4471std::vector<RegisterFlags::Field>::const_iterator overlap =4472std::adjacent_find(fields.begin(), fields.end(),4473[](const RegisterFlags::Field &lhs,4474const RegisterFlags::Field &rhs) {4475return lhs.Overlaps(rhs);4476});44774478// If no fields overlap, use them.4479if (overlap == fields.end()) {4480if (registers_flags_types.contains(*id)) {4481// In theory you could define some flag set, use it with a4482// register then redefine it. We do not know if anyone does4483// that, or what they would expect to happen in that case.4484//4485// LLDB chooses to take the first definition and ignore the rest4486// as waiting until everything has been processed is more4487// expensive and difficult. This means that pointers to flag4488// sets in the register info remain valid if later the flag set4489// is redefined. If we allowed redefinitions, LLDB would crash4490// when you tried to print a register that used the original4491// definition.4492LLDB_LOG(4493log,4494"ProcessGDBRemote::ParseFlags Definition of flags "4495"\"{0}\" shadows "4496"previous definition, using original definition instead.",4497id->data());4498} else {4499registers_flags_types.insert_or_assign(4500*id, std::make_unique<RegisterFlags>(id->str(), *size,4501std::move(fields)));4502}4503} else {4504// If any fields overlap, ignore the whole set of flags.4505std::vector<RegisterFlags::Field>::const_iterator next =4506std::next(overlap);4507LLDB_LOG(4508log,4509"ProcessGDBRemote::ParseFlags Ignoring flags because fields "4510"{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "4511"overlap.",4512overlap->GetName().c_str(), overlap->GetStart(),4513overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),4514next->GetEnd());4515}4516} else {4517LLDB_LOG(4518log,4519"ProcessGDBRemote::ParseFlags Ignoring definition of flags "4520"\"{0}\" because it contains no fields.",4521id->data());4522}4523}45244525return true; // Keep iterating through all "flags" elements.4526});4527}45284529bool ParseRegisters(4530XMLNode feature_node, GdbServerTargetInfo &target_info,4531std::vector<DynamicRegisterInfo::Register> ®isters,4532llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,4533llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {4534if (!feature_node)4535return false;45364537Log *log(GetLog(GDBRLog::Process));45384539// Enums first because they are referenced by fields in the flags.4540ParseEnums(feature_node, registers_enum_types);4541for (const auto &enum_type : registers_enum_types)4542enum_type.second->DumpToLog(log);45434544ParseFlags(feature_node, registers_flags_types, registers_enum_types);4545for (const auto &flags : registers_flags_types)4546flags.second->DumpToLog(log);45474548feature_node.ForEachChildElementWithName(4549"reg",4550[&target_info, ®isters, ®isters_flags_types,4551log](const XMLNode ®_node) -> bool {4552std::string gdb_group;4553std::string gdb_type;4554DynamicRegisterInfo::Register reg_info;4555bool encoding_set = false;4556bool format_set = false;45574558// FIXME: we're silently ignoring invalid data here4559reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type,4560&encoding_set, &format_set, ®_info,4561log](const llvm::StringRef &name,4562const llvm::StringRef &value) -> bool {4563if (name == "name") {4564reg_info.name.SetString(value);4565} else if (name == "bitsize") {4566if (llvm::to_integer(value, reg_info.byte_size))4567reg_info.byte_size =4568llvm::divideCeil(reg_info.byte_size, CHAR_BIT);4569} else if (name == "type") {4570gdb_type = value.str();4571} else if (name == "group") {4572gdb_group = value.str();4573} else if (name == "regnum") {4574llvm::to_integer(value, reg_info.regnum_remote);4575} else if (name == "offset") {4576llvm::to_integer(value, reg_info.byte_offset);4577} else if (name == "altname") {4578reg_info.alt_name.SetString(value);4579} else if (name == "encoding") {4580encoding_set = true;4581reg_info.encoding = Args::StringToEncoding(value, eEncodingUint);4582} else if (name == "format") {4583format_set = true;4584if (!OptionArgParser::ToFormat(value.data(), reg_info.format,4585nullptr)4586.Success())4587reg_info.format =4588llvm::StringSwitch<lldb::Format>(value)4589.Case("vector-sint8", eFormatVectorOfSInt8)4590.Case("vector-uint8", eFormatVectorOfUInt8)4591.Case("vector-sint16", eFormatVectorOfSInt16)4592.Case("vector-uint16", eFormatVectorOfUInt16)4593.Case("vector-sint32", eFormatVectorOfSInt32)4594.Case("vector-uint32", eFormatVectorOfUInt32)4595.Case("vector-float32", eFormatVectorOfFloat32)4596.Case("vector-uint64", eFormatVectorOfUInt64)4597.Case("vector-uint128", eFormatVectorOfUInt128)4598.Default(eFormatInvalid);4599} else if (name == "group_id") {4600uint32_t set_id = UINT32_MAX;4601llvm::to_integer(value, set_id);4602RegisterSetMap::const_iterator pos =4603target_info.reg_set_map.find(set_id);4604if (pos != target_info.reg_set_map.end())4605reg_info.set_name = pos->second.name;4606} else if (name == "gcc_regnum" || name == "ehframe_regnum") {4607llvm::to_integer(value, reg_info.regnum_ehframe);4608} else if (name == "dwarf_regnum") {4609llvm::to_integer(value, reg_info.regnum_dwarf);4610} else if (name == "generic") {4611reg_info.regnum_generic = Args::StringToGenericRegister(value);4612} else if (name == "value_regnums") {4613SplitCommaSeparatedRegisterNumberString(value, reg_info.value_regs,46140);4615} else if (name == "invalidate_regnums") {4616SplitCommaSeparatedRegisterNumberString(4617value, reg_info.invalidate_regs, 0);4618} else {4619LLDB_LOGF(log,4620"ProcessGDBRemote::ParseRegisters unhandled reg "4621"attribute %s = %s",4622name.data(), value.data());4623}4624return true; // Keep iterating through all attributes4625});46264627if (!gdb_type.empty()) {4628// gdb_type could reference some flags type defined in XML.4629llvm::StringMap<std::unique_ptr<RegisterFlags>>::iterator it =4630registers_flags_types.find(gdb_type);4631if (it != registers_flags_types.end()) {4632auto flags_type = it->second.get();4633if (reg_info.byte_size == flags_type->GetSize())4634reg_info.flags_type = flags_type;4635else4636LLDB_LOGF(log,4637"ProcessGDBRemote::ParseRegisters Size of register "4638"flags %s (%d bytes) for "4639"register %s does not match the register size (%d "4640"bytes). Ignoring this set of flags.",4641flags_type->GetID().c_str(), flags_type->GetSize(),4642reg_info.name.AsCString(), reg_info.byte_size);4643}46444645// There's a slim chance that the gdb_type name is both a flags type4646// and a simple type. Just in case, look for that too (setting both4647// does no harm).4648if (!gdb_type.empty() && !(encoding_set || format_set)) {4649if (llvm::StringRef(gdb_type).starts_with("int")) {4650reg_info.format = eFormatHex;4651reg_info.encoding = eEncodingUint;4652} else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {4653reg_info.format = eFormatAddressInfo;4654reg_info.encoding = eEncodingUint;4655} else if (gdb_type == "float") {4656reg_info.format = eFormatFloat;4657reg_info.encoding = eEncodingIEEE754;4658} else if (gdb_type == "aarch64v" ||4659llvm::StringRef(gdb_type).starts_with("vec") ||4660gdb_type == "i387_ext" || gdb_type == "uint128") {4661// lldb doesn't handle 128-bit uints correctly (for ymm*h), so4662// treat them as vector (similarly to xmm/ymm)4663reg_info.format = eFormatVectorOfUInt8;4664reg_info.encoding = eEncodingVector;4665} else {4666LLDB_LOGF(4667log,4668"ProcessGDBRemote::ParseRegisters Could not determine lldb"4669"format and encoding for gdb type %s",4670gdb_type.c_str());4671}4672}4673}46744675// Only update the register set name if we didn't get a "reg_set"4676// attribute. "set_name" will be empty if we didn't have a "reg_set"4677// attribute.4678if (!reg_info.set_name) {4679if (!gdb_group.empty()) {4680reg_info.set_name.SetCString(gdb_group.c_str());4681} else {4682// If no register group name provided anywhere,4683// we'll create a 'general' register set4684reg_info.set_name.SetCString("general");4685}4686}46874688if (reg_info.byte_size == 0) {4689LLDB_LOGF(log,4690"ProcessGDBRemote::%s Skipping zero bitsize register %s",4691__FUNCTION__, reg_info.name.AsCString());4692} else4693registers.push_back(reg_info);46944695return true; // Keep iterating through all "reg" elements4696});4697return true;4698}46994700} // namespace47014702// This method fetches a register description feature xml file from4703// the remote stub and adds registers/register groupsets/architecture4704// information to the current process. It will call itself recursively4705// for nested register definition files. It returns true if it was able4706// to fetch and parse an xml file.4707bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(4708ArchSpec &arch_to_use, std::string xml_filename,4709std::vector<DynamicRegisterInfo::Register> ®isters) {4710// request the target xml file4711llvm::Expected<std::string> raw = m_gdb_comm.ReadExtFeature("features", xml_filename);4712if (errorToBool(raw.takeError()))4713return false;47144715XMLDocument xml_document;47164717if (xml_document.ParseMemory(raw->c_str(), raw->size(),4718xml_filename.c_str())) {4719GdbServerTargetInfo target_info;4720std::vector<XMLNode> feature_nodes;47214722// The top level feature XML file will start with a <target> tag.4723XMLNode target_node = xml_document.GetRootElement("target");4724if (target_node) {4725target_node.ForEachChildElement([&target_info, &feature_nodes](4726const XMLNode &node) -> bool {4727llvm::StringRef name = node.GetName();4728if (name == "architecture") {4729node.GetElementText(target_info.arch);4730} else if (name == "osabi") {4731node.GetElementText(target_info.osabi);4732} else if (name == "xi:include" || name == "include") {4733std::string href = node.GetAttributeValue("href");4734if (!href.empty())4735target_info.includes.push_back(href);4736} else if (name == "feature") {4737feature_nodes.push_back(node);4738} else if (name == "groups") {4739node.ForEachChildElementWithName(4740"group", [&target_info](const XMLNode &node) -> bool {4741uint32_t set_id = UINT32_MAX;4742RegisterSetInfo set_info;47434744node.ForEachAttribute(4745[&set_id, &set_info](const llvm::StringRef &name,4746const llvm::StringRef &value) -> bool {4747// FIXME: we're silently ignoring invalid data here4748if (name == "id")4749llvm::to_integer(value, set_id);4750if (name == "name")4751set_info.name = ConstString(value);4752return true; // Keep iterating through all attributes4753});47544755if (set_id != UINT32_MAX)4756target_info.reg_set_map[set_id] = set_info;4757return true; // Keep iterating through all "group" elements4758});4759}4760return true; // Keep iterating through all children of the target_node4761});4762} else {4763// In an included XML feature file, we're already "inside" the <target>4764// tag of the initial XML file; this included file will likely only have4765// a <feature> tag. Need to check for any more included files in this4766// <feature> element.4767XMLNode feature_node = xml_document.GetRootElement("feature");4768if (feature_node) {4769feature_nodes.push_back(feature_node);4770feature_node.ForEachChildElement([&target_info](4771const XMLNode &node) -> bool {4772llvm::StringRef name = node.GetName();4773if (name == "xi:include" || name == "include") {4774std::string href = node.GetAttributeValue("href");4775if (!href.empty())4776target_info.includes.push_back(href);4777}4778return true;4779});4780}4781}47824783// gdbserver does not implement the LLDB packets used to determine host4784// or process architecture. If that is the case, attempt to use4785// the <architecture/> field from target.xml, e.g.:4786//4787// <architecture>i386:x86-64</architecture> (seen from VMWare ESXi)4788// <architecture>arm</architecture> (seen from Segger JLink on unspecified4789// arm board)4790if (!arch_to_use.IsValid() && !target_info.arch.empty()) {4791// We don't have any information about vendor or OS.4792arch_to_use.SetTriple(llvm::StringSwitch<std::string>(target_info.arch)4793.Case("i386:x86-64", "x86_64")4794.Case("riscv:rv64", "riscv64")4795.Case("riscv:rv32", "riscv32")4796.Default(target_info.arch) +4797"--");47984799if (arch_to_use.IsValid())4800GetTarget().MergeArchitecture(arch_to_use);4801}48024803if (arch_to_use.IsValid()) {4804for (auto &feature_node : feature_nodes) {4805ParseRegisters(feature_node, target_info, registers,4806m_registers_flags_types, m_registers_enum_types);4807}48084809for (const auto &include : target_info.includes) {4810GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include,4811registers);4812}4813}4814} else {4815return false;4816}4817return true;4818}48194820void ProcessGDBRemote::AddRemoteRegisters(4821std::vector<DynamicRegisterInfo::Register> ®isters,4822const ArchSpec &arch_to_use) {4823std::map<uint32_t, uint32_t> remote_to_local_map;4824uint32_t remote_regnum = 0;4825for (auto it : llvm::enumerate(registers)) {4826DynamicRegisterInfo::Register &remote_reg_info = it.value();48274828// Assign successive remote regnums if missing.4829if (remote_reg_info.regnum_remote == LLDB_INVALID_REGNUM)4830remote_reg_info.regnum_remote = remote_regnum;48314832// Create a mapping from remote to local regnos.4833remote_to_local_map[remote_reg_info.regnum_remote] = it.index();48344835remote_regnum = remote_reg_info.regnum_remote + 1;4836}48374838for (DynamicRegisterInfo::Register &remote_reg_info : registers) {4839auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {4840auto lldb_regit = remote_to_local_map.find(process_regnum);4841return lldb_regit != remote_to_local_map.end() ? lldb_regit->second4842: LLDB_INVALID_REGNUM;4843};48444845llvm::transform(remote_reg_info.value_regs,4846remote_reg_info.value_regs.begin(), proc_to_lldb);4847llvm::transform(remote_reg_info.invalidate_regs,4848remote_reg_info.invalidate_regs.begin(), proc_to_lldb);4849}48504851// Don't use Process::GetABI, this code gets called from DidAttach, and4852// in that context we haven't set the Target's architecture yet, so the4853// ABI is also potentially incorrect.4854if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use))4855abi_sp->AugmentRegisterInfo(registers);48564857m_register_info_sp->SetRegisterInfo(std::move(registers), arch_to_use);4858}48594860// query the target of gdb-remote for extended target information returns4861// true on success (got register definitions), false on failure (did not).4862bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {4863// Make sure LLDB has an XML parser it can use first4864if (!XMLDocument::XMLEnabled())4865return false;48664867// check that we have extended feature read support4868if (!m_gdb_comm.GetQXferFeaturesReadSupported())4869return false;48704871// These hold register type information for the whole of target.xml.4872// target.xml may include further documents that4873// GetGDBServerRegisterInfoXMLAndProcess will recurse to fetch and process.4874// That's why we clear the cache here, and not in4875// GetGDBServerRegisterInfoXMLAndProcess. To prevent it being cleared on every4876// include read.4877m_registers_flags_types.clear();4878m_registers_enum_types.clear();4879std::vector<DynamicRegisterInfo::Register> registers;4880if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml",4881registers) &&4882// Target XML is not required to include register information.4883!registers.empty())4884AddRemoteRegisters(registers, arch_to_use);48854886return m_register_info_sp->GetNumRegisters() > 0;4887}48884889llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {4890// Make sure LLDB has an XML parser it can use first4891if (!XMLDocument::XMLEnabled())4892return llvm::createStringError(llvm::inconvertibleErrorCode(),4893"XML parsing not available");48944895Log *log = GetLog(LLDBLog::Process);4896LLDB_LOGF(log, "ProcessGDBRemote::%s", __FUNCTION__);48974898LoadedModuleInfoList list;4899GDBRemoteCommunicationClient &comm = m_gdb_comm;4900bool can_use_svr4 = GetGlobalPluginProperties().GetUseSVR4();49014902// check that we have extended feature read support4903if (can_use_svr4 && comm.GetQXferLibrariesSVR4ReadSupported()) {4904// request the loaded library list4905llvm::Expected<std::string> raw = comm.ReadExtFeature("libraries-svr4", "");4906if (!raw)4907return raw.takeError();49084909// parse the xml file in memory4910LLDB_LOGF(log, "parsing: %s", raw->c_str());4911XMLDocument doc;49124913if (!doc.ParseMemory(raw->c_str(), raw->size(), "noname.xml"))4914return llvm::createStringError(llvm::inconvertibleErrorCode(),4915"Error reading noname.xml");49164917XMLNode root_element = doc.GetRootElement("library-list-svr4");4918if (!root_element)4919return llvm::createStringError(4920llvm::inconvertibleErrorCode(),4921"Error finding library-list-svr4 xml element");49224923// main link map structure4924std::string main_lm = root_element.GetAttributeValue("main-lm");4925// FIXME: we're silently ignoring invalid data here4926if (!main_lm.empty())4927llvm::to_integer(main_lm, list.m_link_map);49284929root_element.ForEachChildElementWithName(4930"library", [log, &list](const XMLNode &library) -> bool {4931LoadedModuleInfoList::LoadedModuleInfo module;49324933// FIXME: we're silently ignoring invalid data here4934library.ForEachAttribute(4935[&module](const llvm::StringRef &name,4936const llvm::StringRef &value) -> bool {4937uint64_t uint_value = LLDB_INVALID_ADDRESS;4938if (name == "name")4939module.set_name(value.str());4940else if (name == "lm") {4941// the address of the link_map struct.4942llvm::to_integer(value, uint_value);4943module.set_link_map(uint_value);4944} else if (name == "l_addr") {4945// the displacement as read from the field 'l_addr' of the4946// link_map struct.4947llvm::to_integer(value, uint_value);4948module.set_base(uint_value);4949// base address is always a displacement, not an absolute4950// value.4951module.set_base_is_offset(true);4952} else if (name == "l_ld") {4953// the memory address of the libraries PT_DYNAMIC section.4954llvm::to_integer(value, uint_value);4955module.set_dynamic(uint_value);4956}49574958return true; // Keep iterating over all properties of "library"4959});49604961if (log) {4962std::string name;4963lldb::addr_t lm = 0, base = 0, ld = 0;4964bool base_is_offset;49654966module.get_name(name);4967module.get_link_map(lm);4968module.get_base(base);4969module.get_base_is_offset(base_is_offset);4970module.get_dynamic(ld);49714972LLDB_LOGF(log,4973"found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx644974"[%s], ld:0x%08" PRIx64 ", name:'%s')",4975lm, base, (base_is_offset ? "offset" : "absolute"), ld,4976name.c_str());4977}49784979list.add(module);4980return true; // Keep iterating over all "library" elements in the root4981// node4982});49834984if (log)4985LLDB_LOGF(log, "found %" PRId32 " modules in total",4986(int)list.m_list.size());4987return list;4988} else if (comm.GetQXferLibrariesReadSupported()) {4989// request the loaded library list4990llvm::Expected<std::string> raw = comm.ReadExtFeature("libraries", "");49914992if (!raw)4993return raw.takeError();49944995LLDB_LOGF(log, "parsing: %s", raw->c_str());4996XMLDocument doc;49974998if (!doc.ParseMemory(raw->c_str(), raw->size(), "noname.xml"))4999return llvm::createStringError(llvm::inconvertibleErrorCode(),5000"Error reading noname.xml");50015002XMLNode root_element = doc.GetRootElement("library-list");5003if (!root_element)5004return llvm::createStringError(llvm::inconvertibleErrorCode(),5005"Error finding library-list xml element");50065007// FIXME: we're silently ignoring invalid data here5008root_element.ForEachChildElementWithName(5009"library", [log, &list](const XMLNode &library) -> bool {5010LoadedModuleInfoList::LoadedModuleInfo module;50115012std::string name = library.GetAttributeValue("name");5013module.set_name(name);50145015// The base address of a given library will be the address of its5016// first section. Most remotes send only one section for Windows5017// targets for example.5018const XMLNode §ion =5019library.FindFirstChildElementWithName("section");5020std::string address = section.GetAttributeValue("address");5021uint64_t address_value = LLDB_INVALID_ADDRESS;5022llvm::to_integer(address, address_value);5023module.set_base(address_value);5024// These addresses are absolute values.5025module.set_base_is_offset(false);50265027if (log) {5028std::string name;5029lldb::addr_t base = 0;5030bool base_is_offset;5031module.get_name(name);5032module.get_base(base);5033module.get_base_is_offset(base_is_offset);50345035LLDB_LOGF(log, "found (base:0x%08" PRIx64 "[%s], name:'%s')", base,5036(base_is_offset ? "offset" : "absolute"), name.c_str());5037}50385039list.add(module);5040return true; // Keep iterating over all "library" elements in the root5041// node5042});50435044if (log)5045LLDB_LOGF(log, "found %" PRId32 " modules in total",5046(int)list.m_list.size());5047return list;5048} else {5049return llvm::createStringError(llvm::inconvertibleErrorCode(),5050"Remote libraries not supported");5051}5052}50535054lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,5055lldb::addr_t link_map,5056lldb::addr_t base_addr,5057bool value_is_offset) {5058DynamicLoader *loader = GetDynamicLoader();5059if (!loader)5060return nullptr;50615062return loader->LoadModuleAtAddress(file, link_map, base_addr,5063value_is_offset);5064}50655066llvm::Error ProcessGDBRemote::LoadModules() {5067using lldb_private::process_gdb_remote::ProcessGDBRemote;50685069// request a list of loaded libraries from GDBServer5070llvm::Expected<LoadedModuleInfoList> module_list = GetLoadedModuleList();5071if (!module_list)5072return module_list.takeError();50735074// get a list of all the modules5075ModuleList new_modules;50765077for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list->m_list) {5078std::string mod_name;5079lldb::addr_t mod_base;5080lldb::addr_t link_map;5081bool mod_base_is_offset;50825083bool valid = true;5084valid &= modInfo.get_name(mod_name);5085valid &= modInfo.get_base(mod_base);5086valid &= modInfo.get_base_is_offset(mod_base_is_offset);5087if (!valid)5088continue;50895090if (!modInfo.get_link_map(link_map))5091link_map = LLDB_INVALID_ADDRESS;50925093FileSpec file(mod_name);5094FileSystem::Instance().Resolve(file);5095lldb::ModuleSP module_sp =5096LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset);50975098if (module_sp.get())5099new_modules.Append(module_sp);5100}51015102if (new_modules.GetSize() > 0) {5103ModuleList removed_modules;5104Target &target = GetTarget();5105ModuleList &loaded_modules = m_process->GetTarget().GetImages();51065107for (size_t i = 0; i < loaded_modules.GetSize(); ++i) {5108const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);51095110bool found = false;5111for (size_t j = 0; j < new_modules.GetSize(); ++j) {5112if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())5113found = true;5114}51155116// The main executable will never be included in libraries-svr4, don't5117// remove it5118if (!found &&5119loaded_module.get() != target.GetExecutableModulePointer()) {5120removed_modules.Append(loaded_module);5121}5122}51235124loaded_modules.Remove(removed_modules);5125m_process->GetTarget().ModulesDidUnload(removed_modules, false);51265127new_modules.ForEach([&target](const lldb::ModuleSP module_sp) -> bool {5128lldb_private::ObjectFile *obj = module_sp->GetObjectFile();5129if (!obj)5130return true;51315132if (obj->GetType() != ObjectFile::Type::eTypeExecutable)5133return true;51345135lldb::ModuleSP module_copy_sp = module_sp;5136target.SetExecutableModule(module_copy_sp, eLoadDependentsNo);5137return false;5138});51395140loaded_modules.AppendIfNeeded(new_modules);5141m_process->GetTarget().ModulesDidLoad(new_modules);5142}51435144return llvm::ErrorSuccess();5145}51465147Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,5148bool &is_loaded,5149lldb::addr_t &load_addr) {5150is_loaded = false;5151load_addr = LLDB_INVALID_ADDRESS;51525153std::string file_path = file.GetPath(false);5154if (file_path.empty())5155return Status("Empty file name specified");51565157StreamString packet;5158packet.PutCString("qFileLoadAddress:");5159packet.PutStringAsRawHex8(file_path);51605161StringExtractorGDBRemote response;5162if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=5163GDBRemoteCommunication::PacketResult::Success)5164return Status("Sending qFileLoadAddress packet failed");51655166if (response.IsErrorResponse()) {5167if (response.GetError() == 1) {5168// The file is not loaded into the inferior5169is_loaded = false;5170load_addr = LLDB_INVALID_ADDRESS;5171return Status();5172}51735174return Status(5175"Fetching file load address from remote server returned an error");5176}51775178if (response.IsNormalResponse()) {5179is_loaded = true;5180load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);5181return Status();5182}51835184return Status(5185"Unknown error happened during sending the load address packet");5186}51875188void ProcessGDBRemote::ModulesDidLoad(ModuleList &module_list) {5189// We must call the lldb_private::Process::ModulesDidLoad () first before we5190// do anything5191Process::ModulesDidLoad(module_list);51925193// After loading shared libraries, we can ask our remote GDB server if it5194// needs any symbols.5195m_gdb_comm.ServeSymbolLookups(this);5196}51975198void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out) {5199AppendSTDOUT(out.data(), out.size());5200}52015202static const char *end_delimiter = "--end--;";5203static const int end_delimiter_len = 8;52045205void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data) {5206std::string input = data.str(); // '1' to move beyond 'A'5207if (m_partial_profile_data.length() > 0) {5208m_partial_profile_data.append(input);5209input = m_partial_profile_data;5210m_partial_profile_data.clear();5211}52125213size_t found, pos = 0, len = input.length();5214while ((found = input.find(end_delimiter, pos)) != std::string::npos) {5215StringExtractorGDBRemote profileDataExtractor(5216input.substr(pos, found).c_str());5217std::string profile_data =5218HarmonizeThreadIdsForProfileData(profileDataExtractor);5219BroadcastAsyncProfileData(profile_data);52205221pos = found + end_delimiter_len;5222}52235224if (pos < len) {5225// Last incomplete chunk.5226m_partial_profile_data = input.substr(pos);5227}5228}52295230std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(5231StringExtractorGDBRemote &profileDataExtractor) {5232std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;5233std::string output;5234llvm::raw_string_ostream output_stream(output);5235llvm::StringRef name, value;52365237// Going to assuming thread_used_usec comes first, else bail out.5238while (profileDataExtractor.GetNameColonValue(name, value)) {5239if (name.compare("thread_used_id") == 0) {5240StringExtractor threadIDHexExtractor(value);5241uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);52425243bool has_used_usec = false;5244uint32_t curr_used_usec = 0;5245llvm::StringRef usec_name, usec_value;5246uint32_t input_file_pos = profileDataExtractor.GetFilePos();5247if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) {5248if (usec_name == "thread_used_usec") {5249has_used_usec = true;5250usec_value.getAsInteger(0, curr_used_usec);5251} else {5252// We didn't find what we want, it is probably an older version. Bail5253// out.5254profileDataExtractor.SetFilePos(input_file_pos);5255}5256}52575258if (has_used_usec) {5259uint32_t prev_used_usec = 0;5260std::map<uint64_t, uint32_t>::iterator iterator =5261m_thread_id_to_used_usec_map.find(thread_id);5262if (iterator != m_thread_id_to_used_usec_map.end()) {5263prev_used_usec = m_thread_id_to_used_usec_map[thread_id];5264}52655266uint32_t real_used_usec = curr_used_usec - prev_used_usec;5267// A good first time record is one that runs for at least 0.25 sec5268bool good_first_time =5269(prev_used_usec == 0) && (real_used_usec > 250000);5270bool good_subsequent_time =5271(prev_used_usec > 0) &&5272((real_used_usec > 0) || (HasAssignedIndexIDToThread(thread_id)));52735274if (good_first_time || good_subsequent_time) {5275// We try to avoid doing too many index id reservation, resulting in5276// fast increase of index ids.52775278output_stream << name << ":";5279int32_t index_id = AssignIndexIDToThread(thread_id);5280output_stream << index_id << ";";52815282output_stream << usec_name << ":" << usec_value << ";";5283} else {5284// Skip past 'thread_used_name'.5285llvm::StringRef local_name, local_value;5286profileDataExtractor.GetNameColonValue(local_name, local_value);5287}52885289// Store current time as previous time so that they can be compared5290// later.5291new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;5292} else {5293// Bail out and use old string.5294output_stream << name << ":" << value << ";";5295}5296} else {5297output_stream << name << ":" << value << ";";5298}5299}5300output_stream << end_delimiter;5301m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;53025303return output_stream.str();5304}53055306void ProcessGDBRemote::HandleStopReply() {5307if (GetStopID() != 0)5308return;53095310if (GetID() == LLDB_INVALID_PROCESS_ID) {5311lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();5312if (pid != LLDB_INVALID_PROCESS_ID)5313SetID(pid);5314}5315BuildDynamicRegisterInfo(true);5316}53175318llvm::Expected<bool> ProcessGDBRemote::SaveCore(llvm::StringRef outfile) {5319if (!m_gdb_comm.GetSaveCoreSupported())5320return false;53215322StreamString packet;5323packet.PutCString("qSaveCore;path-hint:");5324packet.PutStringAsRawHex8(outfile);53255326StringExtractorGDBRemote response;5327if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==5328GDBRemoteCommunication::PacketResult::Success) {5329// TODO: grab error message from the packet? StringExtractor seems to5330// be missing a method for that5331if (response.IsErrorResponse())5332return llvm::createStringError(5333llvm::inconvertibleErrorCode(),5334llvm::formatv("qSaveCore returned an error"));53355336std::string path;53375338// process the response5339for (auto x : llvm::split(response.GetStringRef(), ';')) {5340if (x.consume_front("core-path:"))5341StringExtractor(x).GetHexByteString(path);5342}53435344// verify that we've gotten what we need5345if (path.empty())5346return llvm::createStringError(llvm::inconvertibleErrorCode(),5347"qSaveCore returned no core path");53485349// now transfer the core file5350FileSpec remote_core{llvm::StringRef(path)};5351Platform &platform = *GetTarget().GetPlatform();5352Status error = platform.GetFile(remote_core, FileSpec(outfile));53535354if (platform.IsRemote()) {5355// NB: we unlink the file on error too5356platform.Unlink(remote_core);5357if (error.Fail())5358return error.ToError();5359}53605361return true;5362}53635364return llvm::createStringError(llvm::inconvertibleErrorCode(),5365"Unable to send qSaveCore");5366}53675368static const char *const s_async_json_packet_prefix = "JSON-async:";53695370static StructuredData::ObjectSP5371ParseStructuredDataPacket(llvm::StringRef packet) {5372Log *log = GetLog(GDBRLog::Process);53735374if (!packet.consume_front(s_async_json_packet_prefix)) {5375if (log) {5376LLDB_LOGF(5377log,5378"GDBRemoteCommunicationClientBase::%s() received $J packet "5379"but was not a StructuredData packet: packet starts with "5380"%s",5381__FUNCTION__,5382packet.slice(0, strlen(s_async_json_packet_prefix)).str().c_str());5383}5384return StructuredData::ObjectSP();5385}53865387// This is an asynchronous JSON packet, destined for a StructuredDataPlugin.5388StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet);5389if (log) {5390if (json_sp) {5391StreamString json_str;5392json_sp->Dump(json_str, true);5393json_str.Flush();5394LLDB_LOGF(log,5395"ProcessGDBRemote::%s() "5396"received Async StructuredData packet: %s",5397__FUNCTION__, json_str.GetData());5398} else {5399LLDB_LOGF(log,5400"ProcessGDBRemote::%s"5401"() received StructuredData packet:"5402" parse failure",5403__FUNCTION__);5404}5405}5406return json_sp;5407}54085409void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data) {5410auto structured_data_sp = ParseStructuredDataPacket(data);5411if (structured_data_sp)5412RouteAsyncStructuredData(structured_data_sp);5413}54145415class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed {5416public:5417CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)5418: CommandObjectParsed(interpreter, "process plugin packet speed-test",5419"Tests packet speeds of various sizes to determine "5420"the performance characteristics of the GDB remote "5421"connection. ",5422nullptr),5423m_option_group(),5424m_num_packets(LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount,5425"The number of packets to send of each varying size "5426"(default is 1000).",54271000),5428m_max_send(LLDB_OPT_SET_1, false, "max-send", 's', 0, eArgTypeCount,5429"The maximum number of bytes to send in a packet. Sizes "5430"increase in powers of 2 while the size is less than or "5431"equal to this option value. (default 1024).",54321024),5433m_max_recv(LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount,5434"The maximum number of bytes to receive in a packet. Sizes "5435"increase in powers of 2 while the size is less than or "5436"equal to this option value. (default 1024).",54371024),5438m_json(LLDB_OPT_SET_1, false, "json", 'j',5439"Print the output as JSON data for easy parsing.", false, true) {5440m_option_group.Append(&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);5441m_option_group.Append(&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);5442m_option_group.Append(&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);5443m_option_group.Append(&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);5444m_option_group.Finalize();5445}54465447~CommandObjectProcessGDBRemoteSpeedTest() override = default;54485449Options *GetOptions() override { return &m_option_group; }54505451void DoExecute(Args &command, CommandReturnObject &result) override {5452const size_t argc = command.GetArgumentCount();5453if (argc == 0) {5454ProcessGDBRemote *process =5455(ProcessGDBRemote *)m_interpreter.GetExecutionContext()5456.GetProcessPtr();5457if (process) {5458StreamSP output_stream_sp = result.GetImmediateOutputStream();5459if (!output_stream_sp)5460output_stream_sp =5461StreamSP(m_interpreter.GetDebugger().GetAsyncOutputStream());5462result.SetImmediateOutputStream(output_stream_sp);54635464const uint32_t num_packets =5465(uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();5466const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();5467const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();5468const bool json = m_json.GetOptionValue().GetCurrentValue();5469const uint64_t k_recv_amount =54704 * 1024 * 1024; // Receive amount in bytes5471process->GetGDBRemote().TestPacketSpeed(5472num_packets, max_send, max_recv, k_recv_amount, json,5473output_stream_sp ? *output_stream_sp : result.GetOutputStream());5474result.SetStatus(eReturnStatusSuccessFinishResult);5475return;5476}5477} else {5478result.AppendErrorWithFormat("'%s' takes no arguments",5479m_cmd_name.c_str());5480}5481result.SetStatus(eReturnStatusFailed);5482}54835484protected:5485OptionGroupOptions m_option_group;5486OptionGroupUInt64 m_num_packets;5487OptionGroupUInt64 m_max_send;5488OptionGroupUInt64 m_max_recv;5489OptionGroupBoolean m_json;5490};54915492class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed {5493private:5494public:5495CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)5496: CommandObjectParsed(interpreter, "process plugin packet history",5497"Dumps the packet history buffer. ", nullptr) {}54985499~CommandObjectProcessGDBRemotePacketHistory() override = default;55005501void DoExecute(Args &command, CommandReturnObject &result) override {5502ProcessGDBRemote *process =5503(ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();5504if (process) {5505process->DumpPluginHistory(result.GetOutputStream());5506result.SetStatus(eReturnStatusSuccessFinishResult);5507return;5508}5509result.SetStatus(eReturnStatusFailed);5510}5511};55125513class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed {5514private:5515public:5516CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)5517: CommandObjectParsed(5518interpreter, "process plugin packet xfer-size",5519"Maximum size that lldb will try to read/write one one chunk.",5520nullptr) {5521AddSimpleArgumentList(eArgTypeUnsignedInteger);5522}55235524~CommandObjectProcessGDBRemotePacketXferSize() override = default;55255526void DoExecute(Args &command, CommandReturnObject &result) override {5527const size_t argc = command.GetArgumentCount();5528if (argc == 0) {5529result.AppendErrorWithFormat("'%s' takes an argument to specify the max "5530"amount to be transferred when "5531"reading/writing",5532m_cmd_name.c_str());5533return;5534}55355536ProcessGDBRemote *process =5537(ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();5538if (process) {5539const char *packet_size = command.GetArgumentAtIndex(0);5540errno = 0;5541uint64_t user_specified_max = strtoul(packet_size, nullptr, 10);5542if (errno == 0 && user_specified_max != 0) {5543process->SetUserSpecifiedMaxMemoryTransferSize(user_specified_max);5544result.SetStatus(eReturnStatusSuccessFinishResult);5545return;5546}5547}5548result.SetStatus(eReturnStatusFailed);5549}5550};55515552class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed {5553private:5554public:5555CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)5556: CommandObjectParsed(interpreter, "process plugin packet send",5557"Send a custom packet through the GDB remote "5558"protocol and print the answer. "5559"The packet header and footer will automatically "5560"be added to the packet prior to sending and "5561"stripped from the result.",5562nullptr) {5563AddSimpleArgumentList(eArgTypeNone, eArgRepeatStar);5564}55655566~CommandObjectProcessGDBRemotePacketSend() override = default;55675568void DoExecute(Args &command, CommandReturnObject &result) override {5569const size_t argc = command.GetArgumentCount();5570if (argc == 0) {5571result.AppendErrorWithFormat(5572"'%s' takes a one or more packet content arguments",5573m_cmd_name.c_str());5574return;5575}55765577ProcessGDBRemote *process =5578(ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();5579if (process) {5580for (size_t i = 0; i < argc; ++i) {5581const char *packet_cstr = command.GetArgumentAtIndex(0);5582StringExtractorGDBRemote response;5583process->GetGDBRemote().SendPacketAndWaitForResponse(5584packet_cstr, response, process->GetInterruptTimeout());5585result.SetStatus(eReturnStatusSuccessFinishResult);5586Stream &output_strm = result.GetOutputStream();5587output_strm.Printf(" packet: %s\n", packet_cstr);5588std::string response_str = std::string(response.GetStringRef());55895590if (strstr(packet_cstr, "qGetProfileData") != nullptr) {5591response_str = process->HarmonizeThreadIdsForProfileData(response);5592}55935594if (response_str.empty())5595output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");5596else5597output_strm.Printf("response: %s\n", response.GetStringRef().data());5598}5599}5600}5601};56025603class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw {5604private:5605public:5606CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)5607: CommandObjectRaw(interpreter, "process plugin packet monitor",5608"Send a qRcmd packet through the GDB remote protocol "5609"and print the response."5610"The argument passed to this command will be hex "5611"encoded into a valid 'qRcmd' packet, sent and the "5612"response will be printed.") {}56135614~CommandObjectProcessGDBRemotePacketMonitor() override = default;56155616void DoExecute(llvm::StringRef command,5617CommandReturnObject &result) override {5618if (command.empty()) {5619result.AppendErrorWithFormat("'%s' takes a command string argument",5620m_cmd_name.c_str());5621return;5622}56235624ProcessGDBRemote *process =5625(ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();5626if (process) {5627StreamString packet;5628packet.PutCString("qRcmd,");5629packet.PutBytesAsRawHex8(command.data(), command.size());56305631StringExtractorGDBRemote response;5632Stream &output_strm = result.GetOutputStream();5633process->GetGDBRemote().SendPacketAndReceiveResponseWithOutputSupport(5634packet.GetString(), response, process->GetInterruptTimeout(),5635[&output_strm](llvm::StringRef output) { output_strm << output; });5636result.SetStatus(eReturnStatusSuccessFinishResult);5637output_strm.Printf(" packet: %s\n", packet.GetData());5638const std::string &response_str = std::string(response.GetStringRef());56395640if (response_str.empty())5641output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");5642else5643output_strm.Printf("response: %s\n", response.GetStringRef().data());5644}5645}5646};56475648class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword {5649private:5650public:5651CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)5652: CommandObjectMultiword(interpreter, "process plugin packet",5653"Commands that deal with GDB remote packets.",5654nullptr) {5655LoadSubCommand(5656"history",5657CommandObjectSP(5658new CommandObjectProcessGDBRemotePacketHistory(interpreter)));5659LoadSubCommand(5660"send", CommandObjectSP(5661new CommandObjectProcessGDBRemotePacketSend(interpreter)));5662LoadSubCommand(5663"monitor",5664CommandObjectSP(5665new CommandObjectProcessGDBRemotePacketMonitor(interpreter)));5666LoadSubCommand(5667"xfer-size",5668CommandObjectSP(5669new CommandObjectProcessGDBRemotePacketXferSize(interpreter)));5670LoadSubCommand("speed-test",5671CommandObjectSP(new CommandObjectProcessGDBRemoteSpeedTest(5672interpreter)));5673}56745675~CommandObjectProcessGDBRemotePacket() override = default;5676};56775678class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {5679public:5680CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)5681: CommandObjectMultiword(5682interpreter, "process plugin",5683"Commands for operating on a ProcessGDBRemote process.",5684"process plugin <subcommand> [<subcommand-options>]") {5685LoadSubCommand(5686"packet",5687CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));5688}56895690~CommandObjectMultiwordProcessGDBRemote() override = default;5691};56925693CommandObject *ProcessGDBRemote::GetPluginCommandObject() {5694if (!m_command_sp)5695m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(5696GetTarget().GetDebugger().GetCommandInterpreter());5697return m_command_sp.get();5698}56995700void ProcessGDBRemote::DidForkSwitchSoftwareBreakpoints(bool enable) {5701GetBreakpointSiteList().ForEach([this, enable](BreakpointSite *bp_site) {5702if (bp_site->IsEnabled() &&5703(bp_site->GetType() == BreakpointSite::eSoftware ||5704bp_site->GetType() == BreakpointSite::eExternal)) {5705m_gdb_comm.SendGDBStoppointTypePacket(5706eBreakpointSoftware, enable, bp_site->GetLoadAddress(),5707GetSoftwareBreakpointTrapOpcode(bp_site), GetInterruptTimeout());5708}5709});5710}57115712void ProcessGDBRemote::DidForkSwitchHardwareTraps(bool enable) {5713if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {5714GetBreakpointSiteList().ForEach([this, enable](BreakpointSite *bp_site) {5715if (bp_site->IsEnabled() &&5716bp_site->GetType() == BreakpointSite::eHardware) {5717m_gdb_comm.SendGDBStoppointTypePacket(5718eBreakpointHardware, enable, bp_site->GetLoadAddress(),5719GetSoftwareBreakpointTrapOpcode(bp_site), GetInterruptTimeout());5720}5721});5722}57235724for (const auto &wp_res_sp : m_watchpoint_resource_list.Sites()) {5725addr_t addr = wp_res_sp->GetLoadAddress();5726size_t size = wp_res_sp->GetByteSize();5727GDBStoppointType type = GetGDBStoppointType(wp_res_sp);5728m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,5729GetInterruptTimeout());5730}5731}57325733void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {5734Log *log = GetLog(GDBRLog::Process);57355736lldb::pid_t parent_pid = m_gdb_comm.GetCurrentProcessID();5737// Any valid TID will suffice, thread-relevant actions will set a proper TID5738// anyway.5739lldb::tid_t parent_tid = m_thread_ids.front();57405741lldb::pid_t follow_pid, detach_pid;5742lldb::tid_t follow_tid, detach_tid;57435744switch (GetFollowForkMode()) {5745case eFollowParent:5746follow_pid = parent_pid;5747follow_tid = parent_tid;5748detach_pid = child_pid;5749detach_tid = child_tid;5750break;5751case eFollowChild:5752follow_pid = child_pid;5753follow_tid = child_tid;5754detach_pid = parent_pid;5755detach_tid = parent_tid;5756break;5757}57585759// Switch to the process that is going to be detached.5760if (!m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {5761LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to set pid/tid");5762return;5763}57645765// Disable all software breakpoints in the forked process.5766if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))5767DidForkSwitchSoftwareBreakpoints(false);57685769// Remove hardware breakpoints / watchpoints from parent process if we're5770// following child.5771if (GetFollowForkMode() == eFollowChild)5772DidForkSwitchHardwareTraps(false);57735774// Switch to the process that is going to be followed5775if (!m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||5776!m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {5777LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to reset pid/tid");5778return;5779}57805781LLDB_LOG(log, "Detaching process {0}", detach_pid);5782Status error = m_gdb_comm.Detach(false, detach_pid);5783if (error.Fail()) {5784LLDB_LOG(log, "ProcessGDBRemote::DidFork() detach packet send failed: {0}",5785error.AsCString() ? error.AsCString() : "<unknown error>");5786return;5787}57885789// Hardware breakpoints/watchpoints are not inherited implicitly,5790// so we need to readd them if we're following child.5791if (GetFollowForkMode() == eFollowChild) {5792DidForkSwitchHardwareTraps(true);5793// Update our PID5794SetID(child_pid);5795}5796}57975798void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {5799Log *log = GetLog(GDBRLog::Process);58005801LLDB_LOG(5802log,5803"ProcessGDBRemote::DidFork() called for child_pid: {0}, child_tid {1}",5804child_pid, child_tid);5805++m_vfork_in_progress_count;58065807// Disable all software breakpoints for the duration of vfork.5808if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))5809DidForkSwitchSoftwareBreakpoints(false);58105811lldb::pid_t detach_pid;5812lldb::tid_t detach_tid;58135814switch (GetFollowForkMode()) {5815case eFollowParent:5816detach_pid = child_pid;5817detach_tid = child_tid;5818break;5819case eFollowChild:5820detach_pid = m_gdb_comm.GetCurrentProcessID();5821// Any valid TID will suffice, thread-relevant actions will set a proper TID5822// anyway.5823detach_tid = m_thread_ids.front();58245825// Switch to the parent process before detaching it.5826if (!m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {5827LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to set pid/tid");5828return;5829}58305831// Remove hardware breakpoints / watchpoints from the parent process.5832DidForkSwitchHardwareTraps(false);58335834// Switch to the child process.5835if (!m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||5836!m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {5837LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to reset pid/tid");5838return;5839}5840break;5841}58425843LLDB_LOG(log, "Detaching process {0}", detach_pid);5844Status error = m_gdb_comm.Detach(false, detach_pid);5845if (error.Fail()) {5846LLDB_LOG(log,5847"ProcessGDBRemote::DidFork() detach packet send failed: {0}",5848error.AsCString() ? error.AsCString() : "<unknown error>");5849return;5850}58515852if (GetFollowForkMode() == eFollowChild) {5853// Update our PID5854SetID(child_pid);5855}5856}58575858void ProcessGDBRemote::DidVForkDone() {5859assert(m_vfork_in_progress_count > 0);5860--m_vfork_in_progress_count;58615862// Reenable all software breakpoints that were enabled before vfork.5863if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))5864DidForkSwitchSoftwareBreakpoints(true);5865}58665867void ProcessGDBRemote::DidExec() {5868// If we are following children, vfork is finished by exec (rather than5869// vforkdone that is submitted for parent).5870if (GetFollowForkMode() == eFollowChild) {5871if (m_vfork_in_progress_count > 0)5872--m_vfork_in_progress_count;5873}5874Process::DidExec();5875}587658775878