brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.4 KiB · eb33b52 Raw
522 lines · c
1//===-- ProcessGDBRemote.h --------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H10#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H11 12#include <atomic>13#include <map>14#include <mutex>15#include <optional>16#include <string>17#include <vector>18 19#include "lldb/Core/LoadedModuleInfoList.h"20#include "lldb/Core/ModuleSpec.h"21#include "lldb/Core/ThreadSafeValue.h"22#include "lldb/Host/HostThread.h"23#include "lldb/Target/DynamicRegisterInfo.h"24#include "lldb/Target/Process.h"25#include "lldb/Target/Thread.h"26#include "lldb/Utility/ArchSpec.h"27#include "lldb/Utility/Broadcaster.h"28#include "lldb/Utility/ConstString.h"29#include "lldb/Utility/GDBRemote.h"30#include "lldb/Utility/Status.h"31#include "lldb/Utility/StreamString.h"32#include "lldb/Utility/StringExtractor.h"33#include "lldb/Utility/StringList.h"34#include "lldb/Utility/StructuredData.h"35#include "lldb/lldb-private-forward.h"36 37#include "GDBRemoteCommunicationClient.h"38#include "GDBRemoteRegisterContext.h"39 40#include "llvm/ADT/DenseMap.h"41#include "llvm/ADT/StringMap.h"42 43namespace lldb_private {44namespace process_gdb_remote {45 46class ThreadGDBRemote;47 48class ProcessGDBRemote : public Process,49                         private GDBRemoteClientBase::ContinueDelegate {50public:51  ~ProcessGDBRemote() override;52 53  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,54                                        lldb::ListenerSP listener_sp,55                                        const FileSpec *crash_file_path,56                                        bool can_connect);57 58  static void Initialize();59 60  static void DebuggerInitialize(Debugger &debugger);61 62  static void Terminate();63 64  static llvm::StringRef GetPluginNameStatic() { return "gdb-remote"; }65 66  static llvm::StringRef GetPluginDescriptionStatic();67 68  static std::chrono::seconds GetPacketTimeout();69 70  ArchSpec GetSystemArchitecture() override;71 72  // Check if a given Process73  bool CanDebug(lldb::TargetSP target_sp,74                bool plugin_specified_by_name) override;75 76  CommandObject *GetPluginCommandObject() override;77  78  void DumpPluginHistory(Stream &s) override;79 80  // Creating a new process, or attaching to an existing one81  Status DoWillLaunch(Module *module) override;82 83  Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;84 85  void DidLaunch() override;86 87  Status DoWillAttachToProcessWithID(lldb::pid_t pid) override;88 89  Status DoWillAttachToProcessWithName(const char *process_name,90                                       bool wait_for_launch) override;91 92  Status DoConnectRemote(llvm::StringRef remote_url) override;93 94  Status WillLaunchOrAttach();95 96  Status DoAttachToProcessWithID(lldb::pid_t pid,97                                 const ProcessAttachInfo &attach_info) override;98 99  Status100  DoAttachToProcessWithName(const char *process_name,101                            const ProcessAttachInfo &attach_info) override;102 103  void DidAttach(ArchSpec &process_arch) override;104 105  // PluginInterface protocol106  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }107 108  // Process Control109  Status WillResume() override;110 111  bool SupportsReverseDirection() override;112 113  Status DoResume(lldb::RunDirection direction) override;114 115  Status DoHalt(bool &caused_stop) override;116 117  Status DoDetach(bool keep_stopped) override;118 119  bool DetachRequiresHalt() override { return true; }120 121  Status DoSignal(int signal) override;122 123  Status DoDestroy() override;124 125  void RefreshStateAfterStop() override;126 127  void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);128 129  // Process Queries130  bool IsAlive() override;131 132  lldb::addr_t GetImageInfoAddress() override;133 134  void WillPublicStop() override;135 136  // Process Memory137  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,138                      Status &error) override;139 140  /// Override of ReadMemoryRanges that uses MultiMemRead to optimize this141  /// operation.142  llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>143  ReadMemoryRanges(llvm::ArrayRef<Range<lldb::addr_t, size_t>> ranges,144                   llvm::MutableArrayRef<uint8_t> buf) override;145 146private:147  llvm::Expected<StringExtractorGDBRemote>148  SendMultiMemReadPacket(llvm::ArrayRef<Range<lldb::addr_t, size_t>> ranges);149 150  llvm::Expected<llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>>151  ParseMultiMemReadPacket(llvm::StringRef response_str,152                          llvm::MutableArrayRef<uint8_t> buffer,153                          unsigned expected_num_ranges);154 155public:156  Status157  WriteObjectFile(std::vector<ObjectFile::LoadableData> entries) override;158 159  size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,160                       Status &error) override;161 162  lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,163                                Status &error) override;164 165  Status DoDeallocateMemory(lldb::addr_t ptr) override;166 167  // Process STDIO168  size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override;169 170  // Process Breakpoints171  Status EnableBreakpointSite(BreakpointSite *bp_site) override;172 173  Status DisableBreakpointSite(BreakpointSite *bp_site) override;174 175  // Process Watchpoints176  Status EnableWatchpoint(lldb::WatchpointSP wp_sp,177                          bool notify = true) override;178 179  Status DisableWatchpoint(lldb::WatchpointSP wp_sp,180                           bool notify = true) override;181 182  std::optional<uint32_t> GetWatchpointSlotCount() override;183 184  llvm::Expected<TraceSupportedResponse> TraceSupported() override;185 186  llvm::Error TraceStop(const TraceStopRequest &request) override;187 188  llvm::Error TraceStart(const llvm::json::Value &request) override;189 190  llvm::Expected<std::string> TraceGetState(llvm::StringRef type) override;191 192  llvm::Expected<std::vector<uint8_t>>193  TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;194 195  std::optional<bool> DoGetWatchpointReportedAfter() override;196 197  bool StartNoticingNewThreads() override;198 199  bool StopNoticingNewThreads() override;200 201  GDBRemoteCommunicationClient &GetGDBRemote() { return m_gdb_comm; }202 203  Status SendEventData(const char *data) override;204 205  // Override DidExit so we can disconnect from the remote GDB server206  void DidExit() override;207 208  void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max);209 210  bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,211                     ModuleSpec &module_spec) override;212 213  void PrefetchModuleSpecs(llvm::ArrayRef<FileSpec> module_file_specs,214                           const llvm::Triple &triple) override;215 216  llvm::VersionTuple GetHostOSVersion() override;217  llvm::VersionTuple GetHostMacCatalystVersion() override;218 219  llvm::Error LoadModules() override;220 221  llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() override;222 223  Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded,224                            lldb::addr_t &load_addr) override;225 226  void ModulesDidLoad(ModuleList &module_list) override;227 228  StructuredData::ObjectSP229  GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address,230                                 lldb::addr_t image_count) override;231 232  Status233  ConfigureStructuredData(llvm::StringRef type_name,234                          const StructuredData::ObjectSP &config_sp) override;235 236  StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override;237 238  StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(239      const std::vector<lldb::addr_t> &load_addresses) override;240 241  StructuredData::ObjectSP242  GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args);243 244  StructuredData::ObjectSP GetSharedCacheInfo() override;245 246  StructuredData::ObjectSP GetDynamicLoaderProcessState() override;247 248  std::string HarmonizeThreadIdsForProfileData(249      StringExtractorGDBRemote &inputStringExtractor);250 251  void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;252  void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;253  void DidVForkDone() override;254  void DidExec() override;255 256  llvm::Expected<bool> SaveCore(llvm::StringRef outfile) override;257 258protected:259  friend class ThreadGDBRemote;260  friend class GDBRemoteCommunicationClient;261  friend class GDBRemoteRegisterContext;262 263  ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);264 265  virtual std::shared_ptr<ThreadGDBRemote> CreateThread(lldb::tid_t tid);266 267  bool SupportsMemoryTagging() override;268 269  /// Broadcaster event bits definitions.270  enum {271    eBroadcastBitAsyncContinue = (1 << 0),272    eBroadcastBitAsyncThreadShouldExit = (1 << 1),273    eBroadcastBitAsyncThreadDidExit = (1 << 2)274  };275 276  GDBRemoteCommunicationClient m_gdb_comm;277  std::atomic<lldb::pid_t> m_debugserver_pid;278 279  std::optional<StringExtractorGDBRemote> m_last_stop_packet;280  std::recursive_mutex m_last_stop_packet_mutex;281 282  GDBRemoteDynamicRegisterInfoSP m_register_info_sp;283  Broadcaster m_async_broadcaster;284  lldb::ListenerSP m_async_listener_sp;285  HostThread m_async_thread;286  std::recursive_mutex m_async_thread_state_mutex;287  typedef std::vector<lldb::tid_t> tid_collection;288  typedef std::vector<std::pair<lldb::tid_t, int>> tid_sig_collection;289  typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;290  typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;291  tid_collection m_thread_ids; // Thread IDs for all threads. This list gets292                               // updated after stopping293  std::vector<lldb::addr_t> m_thread_pcs;     // PC values for all the threads.294  StructuredData::ObjectSP m_jstopinfo_sp;    // Stop info only for any threads295                                              // that have valid stop infos296  StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited297                                              // registers and memory for all298                                              // threads if "jThreadsInfo"299                                              // packet is supported300  tid_collection m_continue_c_tids;           // 'c' for continue301  tid_sig_collection m_continue_C_tids;       // 'C' for continue with signal302  tid_collection m_continue_s_tids;           // 's' for step303  tid_sig_collection m_continue_S_tids;       // 'S' for step with signal304  uint64_t m_max_memory_size; // The maximum number of bytes to read/write when305                              // reading and writing memory306  uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote307                                          // gdb stub can handle308  MMapMap m_addr_to_mmap_size;309  lldb::BreakpointSP m_thread_create_bp_sp;310  bool m_waiting_for_attach;311  lldb::CommandObjectSP m_command_sp;312  int64_t m_breakpoint_pc_offset;313  lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach314  bool m_use_g_packet_for_reading;315 316  bool m_allow_flash_writes;317  using FlashRangeVector = lldb_private::RangeVector<lldb::addr_t, size_t>;318  using FlashRange = FlashRangeVector::Entry;319  FlashRangeVector m_erased_flash_ranges;320 321  // Number of vfork() operations being handled.322  uint32_t m_vfork_in_progress_count;323 324  // Accessors325  bool IsRunning(lldb::StateType state) {326    return state == lldb::eStateRunning || IsStepping(state);327  }328 329  bool IsStepping(lldb::StateType state) {330    return state == lldb::eStateStepping;331  }332 333  bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }334 335  bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }336 337  void Clear();338 339  bool DoUpdateThreadList(ThreadList &old_thread_list,340                          ThreadList &new_thread_list) override;341 342  Status EstablishConnectionIfNeeded(const ProcessInfo &process_info);343 344  Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info);345 346  void KillDebugserverProcess();347 348  void BuildDynamicRegisterInfo(bool force);349 350  void SetLastStopPacket(const StringExtractorGDBRemote &response);351 352  bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);353 354  DataExtractor GetAuxvData() override;355 356  StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid);357 358  void GetMaxMemorySize();359 360  bool CalculateThreadStopInfo(ThreadGDBRemote *thread);361 362  size_t UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value);363 364  size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value);365 366  bool StartAsyncThread();367 368  void StopAsyncThread();369 370  lldb::thread_result_t AsyncThread();371 372  static void373  MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,374                            lldb::pid_t pid, int signo, int exit_status);375 376  lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet);377 378  bool379  GetThreadStopInfoFromJSON(ThreadGDBRemote *thread,380                            const StructuredData::ObjectSP &thread_infos_sp);381 382  lldb::ThreadSP SetThreadStopInfo(StructuredData::Dictionary *thread_dict);383 384  lldb::ThreadSP385  SetThreadStopInfo(lldb::tid_t tid,386                    ExpeditedRegisterMap &expedited_register_map, uint8_t signo,387                    const std::string &thread_name, const std::string &reason,388                    const std::string &description, uint32_t exc_type,389                    const std::vector<lldb::addr_t> &exc_data,390                    lldb::addr_t thread_dispatch_qaddr, bool queue_vars_valid,391                    lldb_private::LazyBool associated_with_libdispatch_queue,392                    lldb::addr_t dispatch_queue_t, std::string &queue_name,393                    lldb::QueueKind queue_kind, uint64_t queue_serial);394 395  void ClearThreadIDList();396 397  bool UpdateThreadIDList();398 399  void DidLaunchOrAttach(ArchSpec &process_arch);400  void LoadStubBinaries();401  void MaybeLoadExecutableModule();402 403  Status ConnectToDebugserver(llvm::StringRef host_port);404 405  const char *GetDispatchQueueNameForThread(lldb::addr_t thread_dispatch_qaddr,406                                            std::string &dispatch_queue_name);407 408  DynamicLoader *GetDynamicLoader() override;409 410  bool GetGDBServerRegisterInfoXMLAndProcess(411    ArchSpec &arch_to_use, std::string xml_filename,412    std::vector<DynamicRegisterInfo::Register> &registers);413 414  // Convert DynamicRegisterInfo::Registers into RegisterInfos and add415  // to the dynamic register list.416  void AddRemoteRegisters(std::vector<DynamicRegisterInfo::Register> &registers,417                          const ArchSpec &arch_to_use);418  // Query remote GDBServer for register information419  bool GetGDBServerRegisterInfo(ArchSpec &arch);420 421  lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file,422                                     lldb::addr_t link_map,423                                     lldb::addr_t base_addr,424                                     bool value_is_offset);425 426  Status UpdateAutomaticSignalFiltering() override;427 428  Status FlashErase(lldb::addr_t addr, size_t size);429 430  Status FlashDone();431 432  bool HasErased(FlashRange range);433 434  llvm::Expected<std::vector<uint8_t>>435  DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override;436 437  Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,438                           const std::vector<uint8_t> &tags) override;439 440  Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,441                               MemoryRegionInfo &region_info) override;442 443private:444  // For ProcessGDBRemote only445  std::string m_partial_profile_data;446  std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;447  uint64_t m_last_signals_version = 0;448 449  static bool NewThreadNotifyBreakpointHit(void *baton,450                                           StoppointCallbackContext *context,451                                           lldb::user_id_t break_id,452                                           lldb::user_id_t break_loc_id);453 454  /// Remove the breakpoints associated with thread creation from the Target.455  void RemoveNewThreadBreakpoints();456 457  // ContinueDelegate interface458  void HandleAsyncStdout(llvm::StringRef out) override;459  void HandleAsyncMisc(llvm::StringRef data) override;460  void HandleStopReply() override;461  void HandleAsyncStructuredDataPacket(llvm::StringRef data) override;462 463  lldb::ThreadSP464  HandleThreadAsyncInterrupt(uint8_t signo,465                             const std::string &description) override;466 467  void SetThreadPc(const lldb::ThreadSP &thread_sp, uint64_t index);468  using ModuleCacheKey = std::pair<std::string, std::string>;469  // KeyInfo for the cached module spec DenseMap.470  // The invariant is that all real keys will have the file and architecture471  // set.472  // The empty key has an empty file and an empty arch.473  // The tombstone key has an invalid arch and an empty file.474  // The comparison and hash functions take the file name and architecture475  // triple into account.476  struct ModuleCacheInfo {477    static ModuleCacheKey getEmptyKey() { return ModuleCacheKey(); }478 479    static ModuleCacheKey getTombstoneKey() { return ModuleCacheKey("", "T"); }480 481    static unsigned getHashValue(const ModuleCacheKey &key) {482      return llvm::hash_combine(key.first, key.second);483    }484 485    static bool isEqual(const ModuleCacheKey &LHS, const ModuleCacheKey &RHS) {486      return LHS == RHS;487    }488  };489 490  llvm::DenseMap<ModuleCacheKey, ModuleSpec, ModuleCacheInfo>491      m_cached_module_specs;492 493  ProcessGDBRemote(const ProcessGDBRemote &) = delete;494  const ProcessGDBRemote &operator=(const ProcessGDBRemote &) = delete;495 496  // fork helpers497  void DidForkSwitchSoftwareBreakpoints(bool enable);498  void DidForkSwitchHardwareTraps(bool enable);499 500  void ParseExpeditedRegisters(ExpeditedRegisterMap &expedited_register_map,501                               lldb::ThreadSP thread_sp);502 503  // Lists of register fields generated from the remote's target XML.504  // Pointers to these RegisterFlags will be set in the register info passed505  // back to the upper levels of lldb. Doing so is safe because this class will506  // live at least as long as the debug session. We therefore do not store the507  // data directly in the map because the map may reallocate it's storage as new508  // entries are added. Which would invalidate any pointers set in the register509  // info up to that point.510  llvm::StringMap<std::unique_ptr<RegisterFlags>> m_registers_flags_types;511 512  // Enum types are referenced by register fields. This does not store the data513  // directly because the map may reallocate. Pointers to these are contained514  // within instances of RegisterFlags.515  llvm::StringMap<std::unique_ptr<FieldEnum>> m_registers_enum_types;516};517 518} // namespace process_gdb_remote519} // namespace lldb_private520 521#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H522