1 //===-- MachProcess.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Created by Greg Clayton on 6/15/07. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H 14 #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H 15 16 #include <CoreFoundation/CoreFoundation.h> 17 #include <mach-o/loader.h> 18 #include <mach/mach.h> 19 #include <optional> 20 #include <pthread.h> 21 #include <sys/signal.h> 22 #include <uuid/uuid.h> 23 #include <vector> 24 25 #include "DNBBreakpoint.h" 26 #include "DNBDefs.h" 27 #include "DNBError.h" 28 #include "DNBThreadResumeActions.h" 29 #include "Genealogy.h" 30 #include "JSONGenerator.h" 31 #include "MachException.h" 32 #include "MachTask.h" 33 #include "MachThreadList.h" 34 #include "MachVMMemory.h" 35 #include "PThreadCondition.h" 36 #include "PThreadEvent.h" 37 #include "PThreadMutex.h" 38 #include "RNBContext.h" 39 #include "ThreadInfo.h" 40 41 class DNBThreadResumeActions; 42 43 class MachProcess { 44 public: 45 // Constructors and Destructors 46 MachProcess(); 47 ~MachProcess(); 48 49 // A structure that can hold everything debugserver needs to know from 50 // a binary's Mach-O header / load commands. 51 52 struct mach_o_segment { 53 std::string name; 54 uint64_t vmaddr; 55 uint64_t vmsize; 56 uint64_t fileoff; 57 uint64_t filesize; 58 uint64_t maxprot; 59 uint64_t initprot; 60 uint64_t nsects; 61 uint64_t flags; 62 }; 63 64 struct mach_o_information { 65 struct mach_header_64 mach_header; 66 std::vector<struct mach_o_segment> segments; 67 uuid_t uuid; 68 std::string min_version_os_name; 69 std::string min_version_os_version; 70 }; 71 72 struct binary_image_information { 73 std::string filename; 74 uint64_t load_address; 75 struct mach_o_information macho_info; 76 bool is_valid_mach_header; 77 binary_image_informationbinary_image_information78 binary_image_information() 79 : filename(), load_address(INVALID_NUB_ADDRESS), 80 is_valid_mach_header(false) {} 81 }; 82 83 // Child process control 84 pid_t AttachForDebug(pid_t pid, 85 const RNBContext::IgnoredExceptions &ignored_exceptions, 86 char *err_str, 87 size_t err_len); 88 pid_t LaunchForDebug(const char *path, char const *argv[], char const *envp[], 89 const char *working_directory, const char *stdin_path, 90 const char *stdout_path, const char *stderr_path, 91 bool no_stdio, nub_launch_flavor_t launch_flavor, 92 int disable_aslr, const char *event_data, 93 const RNBContext::IgnoredExceptions &ignored_exceptions, 94 DNBError &err); 95 96 static uint32_t GetCPUTypeForLocalProcess(pid_t pid); 97 static pid_t ForkChildForPTraceDebugging(const char *path, char const *argv[], 98 char const *envp[], 99 MachProcess *process, DNBError &err); 100 static pid_t PosixSpawnChildForPTraceDebugging( 101 const char *path, cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, 102 char const *argv[], char const *envp[], const char *working_directory, 103 const char *stdin_path, const char *stdout_path, const char *stderr_path, 104 bool no_stdio, MachProcess *process, int disable_aslr, DNBError &err); 105 nub_addr_t GetDYLDAllImageInfosAddress(); 106 std::optional<std::pair<cpu_type_t, cpu_subtype_t>> 107 GetMainBinaryCPUTypes(nub_process_t pid); 108 static const void *PrepareForAttach(const char *path, 109 nub_launch_flavor_t launch_flavor, 110 bool waitfor, DNBError &err_str); 111 static void CleanupAfterAttach(const void *attach_token, 112 nub_launch_flavor_t launch_flavor, 113 bool success, DNBError &err_str); 114 static nub_process_t CheckForProcess(const void *attach_token, 115 nub_launch_flavor_t launch_flavor); 116 #if defined(WITH_BKS) || defined(WITH_FBS) 117 pid_t BoardServiceLaunchForDebug(const char *app_bundle_path, 118 char const *argv[], char const *envp[], 119 bool no_stdio, bool disable_aslr, 120 const char *event_data, 121 const RNBContext::IgnoredExceptions &ignored_exceptions, 122 DNBError &launch_err); 123 pid_t BoardServiceForkChildForPTraceDebugging( 124 const char *path, char const *argv[], char const *envp[], bool no_stdio, 125 bool disable_aslr, const char *event_data, DNBError &launch_err); 126 bool BoardServiceSendEvent(const char *event, DNBError &error); 127 #endif 128 static bool GetOSVersionNumbers(uint64_t *major, uint64_t *minor, 129 uint64_t *patch); 130 static std::string GetMacCatalystVersionString(); 131 132 static nub_process_t GetParentProcessID(nub_process_t child_pid); 133 134 static bool ProcessIsBeingDebugged(nub_process_t pid); 135 136 #ifdef WITH_BKS 137 static void BKSCleanupAfterAttach(const void *attach_token, 138 DNBError &err_str); 139 #endif // WITH_BKS 140 #ifdef WITH_FBS 141 static void FBSCleanupAfterAttach(const void *attach_token, 142 DNBError &err_str); 143 #endif // WITH_FBS 144 #ifdef WITH_SPRINGBOARD 145 pid_t SBLaunchForDebug(const char *app_bundle_path, char const *argv[], 146 char const *envp[], bool no_stdio, bool disable_aslr, 147 bool unmask_signals, DNBError &launch_err); 148 static pid_t SBForkChildForPTraceDebugging(const char *path, 149 char const *argv[], 150 char const *envp[], bool no_stdio, 151 MachProcess *process, 152 DNBError &launch_err); 153 #endif // WITH_SPRINGBOARD 154 nub_addr_t LookupSymbol(const char *name, const char *shlib); SetNameToAddressCallback(DNBCallbackNameToAddress callback,void * baton)155 void SetNameToAddressCallback(DNBCallbackNameToAddress callback, 156 void *baton) { 157 m_name_to_addr_callback = callback; 158 m_name_to_addr_baton = baton; 159 } 160 void SetSharedLibraryInfoCallback(DNBCallbackCopyExecutableImageInfos callback,void * baton)161 SetSharedLibraryInfoCallback(DNBCallbackCopyExecutableImageInfos callback, 162 void *baton) { 163 m_image_infos_callback = callback; 164 m_image_infos_baton = baton; 165 } 166 167 bool Resume(const DNBThreadResumeActions &thread_actions); 168 bool Signal(int signal, const struct timespec *timeout_abstime = NULL); 169 bool Interrupt(); 170 bool SendEvent(const char *event, DNBError &send_err); 171 bool Kill(const struct timespec *timeout_abstime = NULL); 172 bool Detach(); 173 nub_size_t ReadMemory(nub_addr_t addr, nub_size_t size, void *buf); 174 nub_size_t WriteMemory(nub_addr_t addr, nub_size_t size, const void *buf); 175 176 // Path and arg accessors Path()177 const char *Path() const { return m_path.c_str(); } ArgumentCount()178 size_t ArgumentCount() const { return m_args.size(); } ArgumentAtIndex(size_t arg_idx)179 const char *ArgumentAtIndex(size_t arg_idx) const { 180 if (arg_idx < m_args.size()) 181 return m_args[arg_idx].c_str(); 182 return NULL; 183 } 184 185 // Breakpoint functions 186 DNBBreakpoint *CreateBreakpoint(nub_addr_t addr, nub_size_t length, 187 bool hardware); 188 bool DisableBreakpoint(nub_addr_t addr, bool remove); 189 void DisableAllBreakpoints(bool remove); 190 bool EnableBreakpoint(nub_addr_t addr); Breakpoints()191 DNBBreakpointList &Breakpoints() { return m_breakpoints; } Breakpoints()192 const DNBBreakpointList &Breakpoints() const { return m_breakpoints; } 193 194 // Watchpoint functions 195 DNBBreakpoint *CreateWatchpoint(nub_addr_t addr, nub_size_t length, 196 uint32_t watch_type, bool hardware); 197 bool DisableWatchpoint(nub_addr_t addr, bool remove); 198 void DisableAllWatchpoints(bool remove); 199 bool EnableWatchpoint(nub_addr_t addr); 200 uint32_t GetNumSupportedHardwareWatchpoints() const; Watchpoints()201 DNBBreakpointList &Watchpoints() { return m_watchpoints; } Watchpoints()202 const DNBBreakpointList &Watchpoints() const { return m_watchpoints; } 203 204 // Exception thread functions 205 bool StartSTDIOThread(); 206 static void *STDIOThread(void *arg); 207 void ExceptionMessageReceived(const MachException::Message &exceptionMessage); 208 task_t ExceptionMessageBundleComplete(); 209 void SharedLibrariesUpdated(); 210 nub_size_t CopyImageInfos(struct DNBExecutableImageInfo **image_infos, 211 bool only_changed); 212 213 // Profile functions 214 void SetEnableAsyncProfiling(bool enable, uint64_t internal_usec, 215 DNBProfileDataScanType scan_type); IsProfilingEnabled()216 bool IsProfilingEnabled() { return m_profile_enabled; } ProfileInterval()217 useconds_t ProfileInterval() { return m_profile_interval_usec; } 218 bool StartProfileThread(); 219 static void *ProfileThread(void *arg); 220 void SignalAsyncProfileData(const char *info); 221 size_t GetAsyncProfileData(char *buf, size_t buf_size); 222 223 // Accessors ProcessID()224 pid_t ProcessID() const { return m_pid; } ProcessIDIsValid()225 bool ProcessIDIsValid() const { return m_pid > 0; } 226 pid_t SetProcessID(pid_t pid); Task()227 MachTask &Task() { return m_task; } Task()228 const MachTask &Task() const { return m_task; } 229 Events()230 PThreadEvent &Events() { return m_events; } 231 const DNBRegisterSetInfo *GetRegisterSetInfo(nub_thread_t tid, 232 nub_size_t *num_reg_sets) const; 233 bool GetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg, 234 DNBRegisterValue *reg_value) const; 235 bool SetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg, 236 const DNBRegisterValue *value) const; 237 nub_bool_t SyncThreadState(nub_thread_t tid); 238 const char *ThreadGetName(nub_thread_t tid); 239 nub_state_t ThreadGetState(nub_thread_t tid); 240 ThreadInfo::QoS GetRequestedQoS(nub_thread_t tid, nub_addr_t tsd, 241 uint64_t dti_qos_class_index); 242 nub_addr_t GetPThreadT(nub_thread_t tid); 243 nub_addr_t GetDispatchQueueT(nub_thread_t tid); 244 nub_addr_t 245 GetTSDAddressForThread(nub_thread_t tid, 246 uint64_t plo_pthread_tsd_base_address_offset, 247 uint64_t plo_pthread_tsd_base_offset, 248 uint64_t plo_pthread_tsd_entry_size); 249 250 struct DeploymentInfo { 251 DeploymentInfo() = default; 252 operator bool() { return platform > 0; } 253 /// The Mach-O platform type; 254 unsigned char platform = 0; 255 uint32_t major_version = 0; 256 uint32_t minor_version = 0; 257 uint32_t patch_version = 0; 258 }; 259 DeploymentInfo GetDeploymentInfo(const struct load_command &, 260 uint64_t load_command_address, 261 bool is_executable); 262 static std::optional<std::string> GetPlatformString(unsigned char platform); 263 bool GetMachOInformationFromMemory(uint32_t platform, 264 nub_addr_t mach_o_header_addr, 265 int wordsize, 266 struct mach_o_information &inf); 267 JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON( 268 const std::vector<struct binary_image_information> &image_infos, 269 bool report_load_commands); 270 uint32_t GetPlatform(); 271 /// Get the runtime platform from DYLD via SPI. 272 uint32_t GetProcessPlatformViaDYLDSPI(); 273 /// Use the dyld SPI present in macOS 10.12, iOS 10, tvOS 10, 274 /// watchOS 3 and newer to get the load address, uuid, and filenames 275 /// of all the libraries. This only fills in those three fields in 276 /// the 'struct binary_image_information' - call 277 /// GetMachOInformationFromMemory to fill in the mach-o header/load 278 /// command details. 279 void GetAllLoadedBinariesViaDYLDSPI( 280 std::vector<struct binary_image_information> &image_infos); 281 JSONGenerator::ObjectSP 282 GetLibrariesInfoForAddresses(nub_process_t pid, 283 std::vector<uint64_t> &macho_addresses); 284 JSONGenerator::ObjectSP 285 GetAllLoadedLibrariesInfos(nub_process_t pid, 286 bool fetch_report_load_commands); 287 JSONGenerator::ObjectSP GetSharedCacheInfo(nub_process_t pid); 288 289 nub_size_t GetNumThreads() const; 290 nub_thread_t GetThreadAtIndex(nub_size_t thread_idx) const; 291 nub_thread_t GetCurrentThread(); 292 nub_thread_t GetCurrentThreadMachPort(); 293 nub_thread_t SetCurrentThread(nub_thread_t tid); GetThreadList()294 MachThreadList &GetThreadList() { return m_thread_list; } 295 bool GetThreadStoppedReason(nub_thread_t tid, 296 struct DNBThreadStopInfo *stop_info); 297 void DumpThreadStoppedReason(nub_thread_t tid) const; 298 const char *GetThreadInfo(nub_thread_t tid) const; 299 300 nub_thread_t GetThreadIDForMachPortNumber(thread_t mach_port_number) const; 301 302 uint32_t GetCPUType(); 303 nub_state_t GetState(); 304 void SetState(nub_state_t state); IsRunning(nub_state_t state)305 bool IsRunning(nub_state_t state) { 306 return state == eStateRunning || IsStepping(state); 307 } IsStepping(nub_state_t state)308 bool IsStepping(nub_state_t state) { return state == eStateStepping; } CanResume(nub_state_t state)309 bool CanResume(nub_state_t state) { return state == eStateStopped; } 310 GetExitStatus(int * status)311 bool GetExitStatus(int *status) { 312 if (GetState() == eStateExited) { 313 if (status) 314 *status = m_exit_status; 315 return true; 316 } 317 return false; 318 } SetExitStatus(int status)319 void SetExitStatus(int status) { 320 m_exit_status = status; 321 SetState(eStateExited); 322 } GetExitInfo()323 const char *GetExitInfo() { return m_exit_info.c_str(); } 324 325 void SetExitInfo(const char *info); 326 StopCount()327 uint32_t StopCount() const { return m_stop_count; } SetChildFileDescriptors(int stdin_fileno,int stdout_fileno,int stderr_fileno)328 void SetChildFileDescriptors(int stdin_fileno, int stdout_fileno, 329 int stderr_fileno) { 330 m_child_stdin = stdin_fileno; 331 m_child_stdout = stdout_fileno; 332 m_child_stderr = stderr_fileno; 333 } 334 GetStdinFileDescriptor()335 int GetStdinFileDescriptor() const { return m_child_stdin; } GetStdoutFileDescriptor()336 int GetStdoutFileDescriptor() const { return m_child_stdout; } GetStderrFileDescriptor()337 int GetStderrFileDescriptor() const { return m_child_stderr; } 338 void AppendSTDOUT(char *s, size_t len); 339 size_t GetAvailableSTDOUT(char *buf, size_t buf_size); 340 size_t GetAvailableSTDERR(char *buf, size_t buf_size); CloseChildFileDescriptors()341 void CloseChildFileDescriptors() { 342 if (m_child_stdin >= 0) { 343 ::close(m_child_stdin); 344 m_child_stdin = -1; 345 } 346 if (m_child_stdout >= 0) { 347 ::close(m_child_stdout); 348 m_child_stdout = -1; 349 } 350 if (m_child_stderr >= 0) { 351 ::close(m_child_stderr); 352 m_child_stderr = -1; 353 } 354 } 355 356 void CalculateBoardStatus(); 357 358 bool ProcessUsingBackBoard(); 359 360 bool ProcessUsingFrontBoard(); 361 362 // Size of addresses in the inferior process (4 or 8). 363 int GetInferiorAddrSize(pid_t pid); 364 365 Genealogy::ThreadActivitySP GetGenealogyInfoForThread(nub_thread_t tid, 366 bool &timed_out); 367 368 Genealogy::ProcessExecutableInfoSP GetGenealogyImageInfo(size_t idx); 369 GetProfileScanType()370 DNBProfileDataScanType GetProfileScanType() { return m_profile_scan_type; } 371 372 JSONGenerator::ObjectSP GetDyldProcessState(); 373 374 private: 375 enum { 376 eMachProcessFlagsNone = 0, 377 eMachProcessFlagsAttached = (1 << 0), 378 eMachProcessFlagsUsingBKS = (1 << 2), // only read via ProcessUsingBackBoard() 379 eMachProcessFlagsUsingFBS = (1 << 3), // only read via ProcessUsingFrontBoard() 380 eMachProcessFlagsBoardCalculated = (1 << 4) 381 }; 382 383 enum { 384 eMachProcessProfileNone = 0, 385 eMachProcessProfileCancel = (1 << 0) 386 }; 387 388 void Clear(bool detaching = false); 389 void ReplyToAllExceptions(); 390 void PrivateResume(); 391 void StopProfileThread(); 392 393 void RefineWatchpointStopInfo(nub_thread_t tid, 394 struct DNBThreadStopInfo *stop_info); 395 Flags()396 uint32_t Flags() const { return m_flags; } 397 nub_state_t DoSIGSTOP(bool clear_bps_and_wps, bool allow_running, 398 uint32_t *thread_idx_ptr); 399 400 pid_t m_pid; // Process ID of child process 401 cpu_type_t m_cpu_type; // The CPU type of this process 402 uint32_t m_platform; // The platform of this process 403 int m_child_stdin; 404 int m_child_stdout; 405 int m_child_stderr; 406 std::string m_path; // A path to the executable if we have one 407 std::vector<std::string> 408 m_args; // The arguments with which the process was lauched 409 int m_exit_status; // The exit status for the process 410 std::string m_exit_info; // Any extra info that we may have about the exit 411 MachTask m_task; // The mach task for this process 412 uint32_t m_flags; // Process specific flags (see eMachProcessFlags enums) 413 uint32_t m_stop_count; // A count of many times have we stopped 414 pthread_t m_stdio_thread; // Thread ID for the thread that watches for child 415 // process stdio 416 PThreadMutex m_stdio_mutex; // Multithreaded protection for stdio 417 std::string m_stdout_data; 418 419 bool m_profile_enabled; // A flag to indicate if profiling is enabled 420 useconds_t m_profile_interval_usec; // If enable, the profiling interval in 421 // microseconds 422 DNBProfileDataScanType 423 m_profile_scan_type; // Indicates what needs to be profiled 424 pthread_t 425 m_profile_thread; // Thread ID for the thread that profiles the inferior 426 PThreadMutex 427 m_profile_data_mutex; // Multithreaded protection for profile info data 428 std::vector<std::string> 429 m_profile_data; // Profile data, must be protected by m_profile_data_mutex 430 PThreadEvent m_profile_events; // Used for the profile thread cancellable wait 431 DNBThreadResumeActions m_thread_actions; // The thread actions for the current 432 // MachProcess::Resume() call 433 MachException::Message::collection m_exception_messages; // A collection of 434 // exception messages 435 // caught when 436 // listening to the 437 // exception port 438 PThreadMutex m_exception_messages_mutex; // Multithreaded protection for 439 // m_exception_messages 440 441 MachThreadList m_thread_list; // A list of threads that is maintained/updated 442 // after each stop 443 Genealogy m_activities; // A list of activities that is updated after every 444 // stop lazily 445 nub_state_t m_state; // The state of our process 446 PThreadMutex m_state_mutex; // Multithreaded protection for m_state 447 PThreadEvent m_events; // Process related events in the child processes 448 // lifetime can be waited upon 449 PThreadEvent m_private_events; // Used to coordinate running and stopping the 450 // process without affecting m_events 451 DNBBreakpointList m_breakpoints; // Breakpoint list for this process 452 DNBBreakpointList m_watchpoints; // Watchpoint list for this process 453 DNBCallbackNameToAddress m_name_to_addr_callback; 454 void *m_name_to_addr_baton; 455 DNBCallbackCopyExecutableImageInfos m_image_infos_callback; 456 void *m_image_infos_baton; 457 std::string 458 m_bundle_id; // If we are a SB or BKS process, this will be our bundle ID. 459 int m_sent_interrupt_signo; // When we call MachProcess::Interrupt(), we want 460 // to send a single signal 461 // to the inferior and only send the signal if we aren't already stopped. 462 // If we end up sending a signal to stop the process we store it until we 463 // receive an exception with this signal. This helps us to verify we got 464 // the signal that interrupted the process. We might stop due to another 465 // reason after an interrupt signal is sent, so this helps us ensure that 466 // we don't report a spurious stop on the next resume. 467 int m_auto_resume_signo; // If we resume the process and still haven't 468 // received our interrupt signal 469 // acknowledgement, we will shortly after the next resume. We store the 470 // interrupt signal in this variable so when we get the interrupt signal 471 // as the sole reason for the process being stopped, we can auto resume 472 // the process. 473 bool m_did_exec; 474 475 void *(*m_dyld_process_info_create)(task_t task, uint64_t timestamp, 476 kern_return_t *kernelError); 477 void (*m_dyld_process_info_for_each_image)( 478 void *info, void (^callback)(uint64_t machHeaderAddress, 479 const uuid_t uuid, const char *path)); 480 void (*m_dyld_process_info_release)(void *info); 481 void (*m_dyld_process_info_get_cache)(void *info, void *cacheInfo); 482 uint32_t (*m_dyld_process_info_get_platform)(void *info); 483 void (*m_dyld_process_info_get_state)(void *info, void *stateInfo); 484 }; 485 486 #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H 487