xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===-- MachProcess.h -------------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick //
9061da546Spatrick //  Created by Greg Clayton on 6/15/07.
10061da546Spatrick //
11061da546Spatrick //===----------------------------------------------------------------------===//
12061da546Spatrick 
13dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H
14dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H
15061da546Spatrick 
16061da546Spatrick #include <CoreFoundation/CoreFoundation.h>
17061da546Spatrick #include <mach-o/loader.h>
18061da546Spatrick #include <mach/mach.h>
19*f6aab3d8Srobert #include <optional>
20061da546Spatrick #include <pthread.h>
21061da546Spatrick #include <sys/signal.h>
22061da546Spatrick #include <uuid/uuid.h>
23061da546Spatrick #include <vector>
24061da546Spatrick 
25061da546Spatrick #include "DNBBreakpoint.h"
26061da546Spatrick #include "DNBDefs.h"
27061da546Spatrick #include "DNBError.h"
28061da546Spatrick #include "DNBThreadResumeActions.h"
29061da546Spatrick #include "Genealogy.h"
30061da546Spatrick #include "JSONGenerator.h"
31061da546Spatrick #include "MachException.h"
32061da546Spatrick #include "MachTask.h"
33061da546Spatrick #include "MachThreadList.h"
34061da546Spatrick #include "MachVMMemory.h"
35061da546Spatrick #include "PThreadCondition.h"
36061da546Spatrick #include "PThreadEvent.h"
37061da546Spatrick #include "PThreadMutex.h"
38*f6aab3d8Srobert #include "RNBContext.h"
39061da546Spatrick #include "ThreadInfo.h"
40061da546Spatrick 
41061da546Spatrick class DNBThreadResumeActions;
42061da546Spatrick 
43061da546Spatrick class MachProcess {
44061da546Spatrick public:
45061da546Spatrick   // Constructors and Destructors
46061da546Spatrick   MachProcess();
47061da546Spatrick   ~MachProcess();
48061da546Spatrick 
49061da546Spatrick   // A structure that can hold everything debugserver needs to know from
50061da546Spatrick   // a binary's Mach-O header / load commands.
51061da546Spatrick 
52061da546Spatrick   struct mach_o_segment {
53061da546Spatrick     std::string name;
54061da546Spatrick     uint64_t vmaddr;
55061da546Spatrick     uint64_t vmsize;
56061da546Spatrick     uint64_t fileoff;
57061da546Spatrick     uint64_t filesize;
58061da546Spatrick     uint64_t maxprot;
59061da546Spatrick     uint64_t initprot;
60061da546Spatrick     uint64_t nsects;
61061da546Spatrick     uint64_t flags;
62061da546Spatrick   };
63061da546Spatrick 
64061da546Spatrick   struct mach_o_information {
65061da546Spatrick     struct mach_header_64 mach_header;
66061da546Spatrick     std::vector<struct mach_o_segment> segments;
67061da546Spatrick     uuid_t uuid;
68061da546Spatrick     std::string min_version_os_name;
69061da546Spatrick     std::string min_version_os_version;
70061da546Spatrick   };
71061da546Spatrick 
72061da546Spatrick   struct binary_image_information {
73061da546Spatrick     std::string filename;
74061da546Spatrick     uint64_t load_address;
75061da546Spatrick     uint64_t mod_date; // may not be available - 0 if so
76061da546Spatrick     struct mach_o_information macho_info;
77*f6aab3d8Srobert     bool is_valid_mach_header;
78061da546Spatrick 
binary_image_informationbinary_image_information79061da546Spatrick     binary_image_information()
80*f6aab3d8Srobert         : filename(), load_address(INVALID_NUB_ADDRESS), mod_date(0),
81*f6aab3d8Srobert           is_valid_mach_header(false) {}
82061da546Spatrick   };
83061da546Spatrick 
84061da546Spatrick   // Child process control
85*f6aab3d8Srobert   pid_t AttachForDebug(pid_t pid,
86*f6aab3d8Srobert                        const RNBContext::IgnoredExceptions &ignored_exceptions,
87*f6aab3d8Srobert                        char *err_str,
88be691f3bSpatrick                        size_t err_len);
89061da546Spatrick   pid_t LaunchForDebug(const char *path, char const *argv[], char const *envp[],
90061da546Spatrick                        const char *working_directory, const char *stdin_path,
91061da546Spatrick                        const char *stdout_path, const char *stderr_path,
92061da546Spatrick                        bool no_stdio, nub_launch_flavor_t launch_flavor,
93be691f3bSpatrick                        int disable_aslr, const char *event_data,
94*f6aab3d8Srobert                        const RNBContext::IgnoredExceptions &ignored_exceptions,
95*f6aab3d8Srobert                        DNBError &err);
96061da546Spatrick 
97061da546Spatrick   static uint32_t GetCPUTypeForLocalProcess(pid_t pid);
98061da546Spatrick   static pid_t ForkChildForPTraceDebugging(const char *path, char const *argv[],
99061da546Spatrick                                            char const *envp[],
100061da546Spatrick                                            MachProcess *process, DNBError &err);
101061da546Spatrick   static pid_t PosixSpawnChildForPTraceDebugging(
102be691f3bSpatrick       const char *path, cpu_type_t cpu_type, cpu_subtype_t cpu_subtype,
103be691f3bSpatrick       char const *argv[], char const *envp[], const char *working_directory,
104be691f3bSpatrick       const char *stdin_path, const char *stdout_path, const char *stderr_path,
105be691f3bSpatrick       bool no_stdio, MachProcess *process, int disable_aslr, DNBError &err);
106061da546Spatrick   nub_addr_t GetDYLDAllImageInfosAddress();
107061da546Spatrick   static const void *PrepareForAttach(const char *path,
108061da546Spatrick                                       nub_launch_flavor_t launch_flavor,
109061da546Spatrick                                       bool waitfor, DNBError &err_str);
110061da546Spatrick   static void CleanupAfterAttach(const void *attach_token,
111061da546Spatrick                                  nub_launch_flavor_t launch_flavor,
112061da546Spatrick                                  bool success, DNBError &err_str);
113061da546Spatrick   static nub_process_t CheckForProcess(const void *attach_token,
114061da546Spatrick                                        nub_launch_flavor_t launch_flavor);
115061da546Spatrick #if defined(WITH_BKS) || defined(WITH_FBS)
116061da546Spatrick   pid_t BoardServiceLaunchForDebug(const char *app_bundle_path,
117061da546Spatrick                                    char const *argv[], char const *envp[],
118061da546Spatrick                                    bool no_stdio, bool disable_aslr,
119*f6aab3d8Srobert                                    const char *event_data,
120*f6aab3d8Srobert                                    const RNBContext::IgnoredExceptions &ignored_exceptions,
121061da546Spatrick                                    DNBError &launch_err);
122061da546Spatrick   pid_t BoardServiceForkChildForPTraceDebugging(
123061da546Spatrick       const char *path, char const *argv[], char const *envp[], bool no_stdio,
124061da546Spatrick       bool disable_aslr, const char *event_data, DNBError &launch_err);
125061da546Spatrick   bool BoardServiceSendEvent(const char *event, DNBError &error);
126061da546Spatrick #endif
127061da546Spatrick   static bool GetOSVersionNumbers(uint64_t *major, uint64_t *minor,
128061da546Spatrick                                   uint64_t *patch);
129061da546Spatrick   static std::string GetMacCatalystVersionString();
130061da546Spatrick #ifdef WITH_BKS
131061da546Spatrick   static void BKSCleanupAfterAttach(const void *attach_token,
132061da546Spatrick                                     DNBError &err_str);
133061da546Spatrick #endif // WITH_BKS
134061da546Spatrick #ifdef WITH_FBS
135061da546Spatrick   static void FBSCleanupAfterAttach(const void *attach_token,
136061da546Spatrick                                     DNBError &err_str);
137061da546Spatrick #endif // WITH_FBS
138061da546Spatrick #ifdef WITH_SPRINGBOARD
139061da546Spatrick   pid_t SBLaunchForDebug(const char *app_bundle_path, char const *argv[],
140061da546Spatrick                          char const *envp[], bool no_stdio, bool disable_aslr,
141be691f3bSpatrick                          bool unmask_signals, DNBError &launch_err);
142061da546Spatrick   static pid_t SBForkChildForPTraceDebugging(const char *path,
143061da546Spatrick                                              char const *argv[],
144061da546Spatrick                                              char const *envp[], bool no_stdio,
145061da546Spatrick                                              MachProcess *process,
146061da546Spatrick                                              DNBError &launch_err);
147061da546Spatrick #endif // WITH_SPRINGBOARD
148061da546Spatrick   nub_addr_t LookupSymbol(const char *name, const char *shlib);
SetNameToAddressCallback(DNBCallbackNameToAddress callback,void * baton)149061da546Spatrick   void SetNameToAddressCallback(DNBCallbackNameToAddress callback,
150061da546Spatrick                                 void *baton) {
151061da546Spatrick     m_name_to_addr_callback = callback;
152061da546Spatrick     m_name_to_addr_baton = baton;
153061da546Spatrick   }
154061da546Spatrick   void
SetSharedLibraryInfoCallback(DNBCallbackCopyExecutableImageInfos callback,void * baton)155061da546Spatrick   SetSharedLibraryInfoCallback(DNBCallbackCopyExecutableImageInfos callback,
156061da546Spatrick                                void *baton) {
157061da546Spatrick     m_image_infos_callback = callback;
158061da546Spatrick     m_image_infos_baton = baton;
159061da546Spatrick   }
160061da546Spatrick 
161061da546Spatrick   bool Resume(const DNBThreadResumeActions &thread_actions);
162061da546Spatrick   bool Signal(int signal, const struct timespec *timeout_abstime = NULL);
163061da546Spatrick   bool Interrupt();
164061da546Spatrick   bool SendEvent(const char *event, DNBError &send_err);
165061da546Spatrick   bool Kill(const struct timespec *timeout_abstime = NULL);
166061da546Spatrick   bool Detach();
167061da546Spatrick   nub_size_t ReadMemory(nub_addr_t addr, nub_size_t size, void *buf);
168061da546Spatrick   nub_size_t WriteMemory(nub_addr_t addr, nub_size_t size, const void *buf);
169061da546Spatrick 
170061da546Spatrick   // Path and arg accessors
Path()171061da546Spatrick   const char *Path() const { return m_path.c_str(); }
ArgumentCount()172061da546Spatrick   size_t ArgumentCount() const { return m_args.size(); }
ArgumentAtIndex(size_t arg_idx)173061da546Spatrick   const char *ArgumentAtIndex(size_t arg_idx) const {
174061da546Spatrick     if (arg_idx < m_args.size())
175061da546Spatrick       return m_args[arg_idx].c_str();
176061da546Spatrick     return NULL;
177061da546Spatrick   }
178061da546Spatrick 
179061da546Spatrick   // Breakpoint functions
180061da546Spatrick   DNBBreakpoint *CreateBreakpoint(nub_addr_t addr, nub_size_t length,
181061da546Spatrick                                   bool hardware);
182061da546Spatrick   bool DisableBreakpoint(nub_addr_t addr, bool remove);
183061da546Spatrick   void DisableAllBreakpoints(bool remove);
184061da546Spatrick   bool EnableBreakpoint(nub_addr_t addr);
Breakpoints()185061da546Spatrick   DNBBreakpointList &Breakpoints() { return m_breakpoints; }
Breakpoints()186061da546Spatrick   const DNBBreakpointList &Breakpoints() const { return m_breakpoints; }
187061da546Spatrick 
188061da546Spatrick   // Watchpoint functions
189061da546Spatrick   DNBBreakpoint *CreateWatchpoint(nub_addr_t addr, nub_size_t length,
190061da546Spatrick                                   uint32_t watch_type, bool hardware);
191061da546Spatrick   bool DisableWatchpoint(nub_addr_t addr, bool remove);
192061da546Spatrick   void DisableAllWatchpoints(bool remove);
193061da546Spatrick   bool EnableWatchpoint(nub_addr_t addr);
194061da546Spatrick   uint32_t GetNumSupportedHardwareWatchpoints() const;
Watchpoints()195061da546Spatrick   DNBBreakpointList &Watchpoints() { return m_watchpoints; }
Watchpoints()196061da546Spatrick   const DNBBreakpointList &Watchpoints() const { return m_watchpoints; }
197061da546Spatrick 
198061da546Spatrick   // Exception thread functions
199061da546Spatrick   bool StartSTDIOThread();
200061da546Spatrick   static void *STDIOThread(void *arg);
201061da546Spatrick   void ExceptionMessageReceived(const MachException::Message &exceptionMessage);
202061da546Spatrick   task_t ExceptionMessageBundleComplete();
203061da546Spatrick   void SharedLibrariesUpdated();
204061da546Spatrick   nub_size_t CopyImageInfos(struct DNBExecutableImageInfo **image_infos,
205061da546Spatrick                             bool only_changed);
206061da546Spatrick 
207061da546Spatrick   // Profile functions
208061da546Spatrick   void SetEnableAsyncProfiling(bool enable, uint64_t internal_usec,
209061da546Spatrick                                DNBProfileDataScanType scan_type);
IsProfilingEnabled()210061da546Spatrick   bool IsProfilingEnabled() { return m_profile_enabled; }
ProfileInterval()211061da546Spatrick   useconds_t ProfileInterval() { return m_profile_interval_usec; }
212061da546Spatrick   bool StartProfileThread();
213061da546Spatrick   static void *ProfileThread(void *arg);
214061da546Spatrick   void SignalAsyncProfileData(const char *info);
215061da546Spatrick   size_t GetAsyncProfileData(char *buf, size_t buf_size);
216061da546Spatrick 
217061da546Spatrick   // Accessors
ProcessID()218061da546Spatrick   pid_t ProcessID() const { return m_pid; }
ProcessIDIsValid()219061da546Spatrick   bool ProcessIDIsValid() const { return m_pid > 0; }
220061da546Spatrick   pid_t SetProcessID(pid_t pid);
Task()221061da546Spatrick   MachTask &Task() { return m_task; }
Task()222061da546Spatrick   const MachTask &Task() const { return m_task; }
223061da546Spatrick 
Events()224061da546Spatrick   PThreadEvent &Events() { return m_events; }
225061da546Spatrick   const DNBRegisterSetInfo *GetRegisterSetInfo(nub_thread_t tid,
226061da546Spatrick                                                nub_size_t *num_reg_sets) const;
227061da546Spatrick   bool GetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg,
228061da546Spatrick                         DNBRegisterValue *reg_value) const;
229061da546Spatrick   bool SetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg,
230061da546Spatrick                         const DNBRegisterValue *value) const;
231061da546Spatrick   nub_bool_t SyncThreadState(nub_thread_t tid);
232061da546Spatrick   const char *ThreadGetName(nub_thread_t tid);
233061da546Spatrick   nub_state_t ThreadGetState(nub_thread_t tid);
234061da546Spatrick   ThreadInfo::QoS GetRequestedQoS(nub_thread_t tid, nub_addr_t tsd,
235061da546Spatrick                                   uint64_t dti_qos_class_index);
236061da546Spatrick   nub_addr_t GetPThreadT(nub_thread_t tid);
237061da546Spatrick   nub_addr_t GetDispatchQueueT(nub_thread_t tid);
238061da546Spatrick   nub_addr_t
239061da546Spatrick   GetTSDAddressForThread(nub_thread_t tid,
240061da546Spatrick                          uint64_t plo_pthread_tsd_base_address_offset,
241061da546Spatrick                          uint64_t plo_pthread_tsd_base_offset,
242061da546Spatrick                          uint64_t plo_pthread_tsd_entry_size);
243dda28197Spatrick 
244dda28197Spatrick   struct DeploymentInfo {
245dda28197Spatrick     DeploymentInfo() = default;
246dda28197Spatrick     operator bool() { return platform > 0; }
247dda28197Spatrick     /// The Mach-O platform type;
248dda28197Spatrick     unsigned char platform = 0;
249dda28197Spatrick     uint32_t major_version = 0;
250dda28197Spatrick     uint32_t minor_version = 0;
251dda28197Spatrick     uint32_t patch_version = 0;
252dda28197Spatrick   };
253dda28197Spatrick   DeploymentInfo GetDeploymentInfo(const struct load_command &,
254be691f3bSpatrick                                    uint64_t load_command_address,
255be691f3bSpatrick                                    bool is_executable);
256*f6aab3d8Srobert   static std::optional<std::string> GetPlatformString(unsigned char platform);
257061da546Spatrick   bool GetMachOInformationFromMemory(uint32_t platform,
258061da546Spatrick                                      nub_addr_t mach_o_header_addr,
259061da546Spatrick                                      int wordsize,
260061da546Spatrick                                      struct mach_o_information &inf);
261061da546Spatrick   JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON(
262061da546Spatrick       const std::vector<struct binary_image_information> &image_infos);
263be691f3bSpatrick   uint32_t GetPlatform();
264be691f3bSpatrick   /// Get the runtime platform from DYLD via SPI.
265be691f3bSpatrick   uint32_t GetProcessPlatformViaDYLDSPI();
266be691f3bSpatrick   /// Use the dyld SPI present in macOS 10.12, iOS 10, tvOS 10,
267be691f3bSpatrick   /// watchOS 3 and newer to get the load address, uuid, and filenames
268be691f3bSpatrick   /// of all the libraries.  This only fills in those three fields in
269be691f3bSpatrick   /// the 'struct binary_image_information' - call
270be691f3bSpatrick   /// GetMachOInformationFromMemory to fill in the mach-o header/load
271be691f3bSpatrick   /// command details.
272be691f3bSpatrick   void GetAllLoadedBinariesViaDYLDSPI(
273061da546Spatrick       std::vector<struct binary_image_information> &image_infos);
274061da546Spatrick   JSONGenerator::ObjectSP GetLoadedDynamicLibrariesInfos(
275061da546Spatrick       nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
276061da546Spatrick   JSONGenerator::ObjectSP
277061da546Spatrick   GetLibrariesInfoForAddresses(nub_process_t pid,
278061da546Spatrick                                std::vector<uint64_t> &macho_addresses);
279061da546Spatrick   JSONGenerator::ObjectSP GetAllLoadedLibrariesInfos(nub_process_t pid);
280061da546Spatrick   JSONGenerator::ObjectSP GetSharedCacheInfo(nub_process_t pid);
281061da546Spatrick 
282061da546Spatrick   nub_size_t GetNumThreads() const;
283061da546Spatrick   nub_thread_t GetThreadAtIndex(nub_size_t thread_idx) const;
284061da546Spatrick   nub_thread_t GetCurrentThread();
285061da546Spatrick   nub_thread_t GetCurrentThreadMachPort();
286061da546Spatrick   nub_thread_t SetCurrentThread(nub_thread_t tid);
GetThreadList()287061da546Spatrick   MachThreadList &GetThreadList() { return m_thread_list; }
288061da546Spatrick   bool GetThreadStoppedReason(nub_thread_t tid,
289061da546Spatrick                               struct DNBThreadStopInfo *stop_info);
290061da546Spatrick   void DumpThreadStoppedReason(nub_thread_t tid) const;
291061da546Spatrick   const char *GetThreadInfo(nub_thread_t tid) const;
292061da546Spatrick 
293061da546Spatrick   nub_thread_t GetThreadIDForMachPortNumber(thread_t mach_port_number) const;
294061da546Spatrick 
295061da546Spatrick   uint32_t GetCPUType();
296061da546Spatrick   nub_state_t GetState();
297061da546Spatrick   void SetState(nub_state_t state);
IsRunning(nub_state_t state)298061da546Spatrick   bool IsRunning(nub_state_t state) {
299061da546Spatrick     return state == eStateRunning || IsStepping(state);
300061da546Spatrick   }
IsStepping(nub_state_t state)301061da546Spatrick   bool IsStepping(nub_state_t state) { return state == eStateStepping; }
CanResume(nub_state_t state)302061da546Spatrick   bool CanResume(nub_state_t state) { return state == eStateStopped; }
303061da546Spatrick 
GetExitStatus(int * status)304061da546Spatrick   bool GetExitStatus(int *status) {
305061da546Spatrick     if (GetState() == eStateExited) {
306061da546Spatrick       if (status)
307061da546Spatrick         *status = m_exit_status;
308061da546Spatrick       return true;
309061da546Spatrick     }
310061da546Spatrick     return false;
311061da546Spatrick   }
SetExitStatus(int status)312061da546Spatrick   void SetExitStatus(int status) {
313061da546Spatrick     m_exit_status = status;
314061da546Spatrick     SetState(eStateExited);
315061da546Spatrick   }
GetExitInfo()316061da546Spatrick   const char *GetExitInfo() { return m_exit_info.c_str(); }
317061da546Spatrick 
318061da546Spatrick   void SetExitInfo(const char *info);
319061da546Spatrick 
StopCount()320061da546Spatrick   uint32_t StopCount() const { return m_stop_count; }
SetChildFileDescriptors(int stdin_fileno,int stdout_fileno,int stderr_fileno)321061da546Spatrick   void SetChildFileDescriptors(int stdin_fileno, int stdout_fileno,
322061da546Spatrick                                int stderr_fileno) {
323061da546Spatrick     m_child_stdin = stdin_fileno;
324061da546Spatrick     m_child_stdout = stdout_fileno;
325061da546Spatrick     m_child_stderr = stderr_fileno;
326061da546Spatrick   }
327061da546Spatrick 
GetStdinFileDescriptor()328061da546Spatrick   int GetStdinFileDescriptor() const { return m_child_stdin; }
GetStdoutFileDescriptor()329061da546Spatrick   int GetStdoutFileDescriptor() const { return m_child_stdout; }
GetStderrFileDescriptor()330061da546Spatrick   int GetStderrFileDescriptor() const { return m_child_stderr; }
331061da546Spatrick   void AppendSTDOUT(char *s, size_t len);
332061da546Spatrick   size_t GetAvailableSTDOUT(char *buf, size_t buf_size);
333061da546Spatrick   size_t GetAvailableSTDERR(char *buf, size_t buf_size);
CloseChildFileDescriptors()334061da546Spatrick   void CloseChildFileDescriptors() {
335061da546Spatrick     if (m_child_stdin >= 0) {
336061da546Spatrick       ::close(m_child_stdin);
337061da546Spatrick       m_child_stdin = -1;
338061da546Spatrick     }
339061da546Spatrick     if (m_child_stdout >= 0) {
340061da546Spatrick       ::close(m_child_stdout);
341061da546Spatrick       m_child_stdout = -1;
342061da546Spatrick     }
343061da546Spatrick     if (m_child_stderr >= 0) {
344061da546Spatrick       ::close(m_child_stderr);
345061da546Spatrick       m_child_stderr = -1;
346061da546Spatrick     }
347061da546Spatrick   }
348061da546Spatrick 
349061da546Spatrick   void CalculateBoardStatus();
350061da546Spatrick 
351061da546Spatrick   bool ProcessUsingBackBoard();
352061da546Spatrick 
353061da546Spatrick   bool ProcessUsingFrontBoard();
354061da546Spatrick 
355be691f3bSpatrick   // Size of addresses in the inferior process (4 or 8).
356be691f3bSpatrick   int GetInferiorAddrSize(pid_t pid);
357be691f3bSpatrick 
358061da546Spatrick   Genealogy::ThreadActivitySP GetGenealogyInfoForThread(nub_thread_t tid,
359061da546Spatrick                                                         bool &timed_out);
360061da546Spatrick 
361061da546Spatrick   Genealogy::ProcessExecutableInfoSP GetGenealogyImageInfo(size_t idx);
362061da546Spatrick 
GetProfileScanType()363061da546Spatrick   DNBProfileDataScanType GetProfileScanType() { return m_profile_scan_type; }
364061da546Spatrick 
365*f6aab3d8Srobert   JSONGenerator::ObjectSP GetDyldProcessState();
366*f6aab3d8Srobert 
367061da546Spatrick private:
368061da546Spatrick   enum {
369061da546Spatrick     eMachProcessFlagsNone = 0,
370061da546Spatrick     eMachProcessFlagsAttached = (1 << 0),
371061da546Spatrick     eMachProcessFlagsUsingBKS = (1 << 2), // only read via ProcessUsingBackBoard()
372061da546Spatrick     eMachProcessFlagsUsingFBS = (1 << 3), // only read via ProcessUsingFrontBoard()
373061da546Spatrick     eMachProcessFlagsBoardCalculated = (1 << 4)
374061da546Spatrick   };
375dda28197Spatrick 
376dda28197Spatrick   enum {
377dda28197Spatrick     eMachProcessProfileNone = 0,
378dda28197Spatrick     eMachProcessProfileCancel = (1 << 0)
379dda28197Spatrick   };
380dda28197Spatrick 
381061da546Spatrick   void Clear(bool detaching = false);
382061da546Spatrick   void ReplyToAllExceptions();
383061da546Spatrick   void PrivateResume();
384dda28197Spatrick   void StopProfileThread();
385061da546Spatrick 
Flags()386061da546Spatrick   uint32_t Flags() const { return m_flags; }
387061da546Spatrick   nub_state_t DoSIGSTOP(bool clear_bps_and_wps, bool allow_running,
388061da546Spatrick                         uint32_t *thread_idx_ptr);
389061da546Spatrick 
390061da546Spatrick   pid_t m_pid;           // Process ID of child process
391061da546Spatrick   cpu_type_t m_cpu_type; // The CPU type of this process
392be691f3bSpatrick   uint32_t m_platform;   // The platform of this process
393061da546Spatrick   int m_child_stdin;
394061da546Spatrick   int m_child_stdout;
395061da546Spatrick   int m_child_stderr;
396061da546Spatrick   std::string m_path; // A path to the executable if we have one
397061da546Spatrick   std::vector<std::string>
398061da546Spatrick       m_args;              // The arguments with which the process was lauched
399061da546Spatrick   int m_exit_status;       // The exit status for the process
400061da546Spatrick   std::string m_exit_info; // Any extra info that we may have about the exit
401061da546Spatrick   MachTask m_task;         // The mach task for this process
402061da546Spatrick   uint32_t m_flags;      // Process specific flags (see eMachProcessFlags enums)
403061da546Spatrick   uint32_t m_stop_count; // A count of many times have we stopped
404061da546Spatrick   pthread_t m_stdio_thread;   // Thread ID for the thread that watches for child
405061da546Spatrick                               // process stdio
406061da546Spatrick   PThreadMutex m_stdio_mutex; // Multithreaded protection for stdio
407061da546Spatrick   std::string m_stdout_data;
408061da546Spatrick 
409061da546Spatrick   bool m_profile_enabled; // A flag to indicate if profiling is enabled
410061da546Spatrick   useconds_t m_profile_interval_usec; // If enable, the profiling interval in
411061da546Spatrick                                       // microseconds
412061da546Spatrick   DNBProfileDataScanType
413061da546Spatrick       m_profile_scan_type; // Indicates what needs to be profiled
414061da546Spatrick   pthread_t
415061da546Spatrick       m_profile_thread; // Thread ID for the thread that profiles the inferior
416061da546Spatrick   PThreadMutex
417061da546Spatrick       m_profile_data_mutex; // Multithreaded protection for profile info data
418061da546Spatrick   std::vector<std::string>
419061da546Spatrick       m_profile_data; // Profile data, must be protected by m_profile_data_mutex
420dda28197Spatrick   PThreadEvent m_profile_events; // Used for the profile thread cancellable wait
421061da546Spatrick   DNBThreadResumeActions m_thread_actions; // The thread actions for the current
422061da546Spatrick                                            // MachProcess::Resume() call
423061da546Spatrick   MachException::Message::collection m_exception_messages; // A collection of
424061da546Spatrick                                                            // exception messages
425061da546Spatrick                                                            // caught when
426061da546Spatrick                                                            // listening to the
427061da546Spatrick                                                            // exception port
428061da546Spatrick   PThreadMutex m_exception_messages_mutex; // Multithreaded protection for
429061da546Spatrick                                            // m_exception_messages
430061da546Spatrick 
431061da546Spatrick   MachThreadList m_thread_list; // A list of threads that is maintained/updated
432061da546Spatrick                                 // after each stop
433061da546Spatrick   Genealogy m_activities; // A list of activities that is updated after every
434061da546Spatrick                           // stop lazily
435061da546Spatrick   nub_state_t m_state;    // The state of our process
436061da546Spatrick   PThreadMutex m_state_mutex; // Multithreaded protection for m_state
437061da546Spatrick   PThreadEvent m_events;      // Process related events in the child processes
438061da546Spatrick                               // lifetime can be waited upon
439061da546Spatrick   PThreadEvent m_private_events; // Used to coordinate running and stopping the
440061da546Spatrick                                  // process without affecting m_events
441061da546Spatrick   DNBBreakpointList m_breakpoints; // Breakpoint list for this process
442061da546Spatrick   DNBBreakpointList m_watchpoints; // Watchpoint list for this process
443061da546Spatrick   DNBCallbackNameToAddress m_name_to_addr_callback;
444061da546Spatrick   void *m_name_to_addr_baton;
445061da546Spatrick   DNBCallbackCopyExecutableImageInfos m_image_infos_callback;
446061da546Spatrick   void *m_image_infos_baton;
447061da546Spatrick   std::string
448061da546Spatrick       m_bundle_id; // If we are a SB or BKS process, this will be our bundle ID.
449061da546Spatrick   int m_sent_interrupt_signo; // When we call MachProcess::Interrupt(), we want
450061da546Spatrick                               // to send a single signal
451061da546Spatrick   // to the inferior and only send the signal if we aren't already stopped.
452061da546Spatrick   // If we end up sending a signal to stop the process we store it until we
453061da546Spatrick   // receive an exception with this signal. This helps us to verify we got
454061da546Spatrick   // the signal that interrupted the process. We might stop due to another
455061da546Spatrick   // reason after an interrupt signal is sent, so this helps us ensure that
456061da546Spatrick   // we don't report a spurious stop on the next resume.
457061da546Spatrick   int m_auto_resume_signo; // If we resume the process and still haven't
458061da546Spatrick                            // received our interrupt signal
459dda28197Spatrick   // acknowledgement, we will shortly after the next resume. We store the
460061da546Spatrick   // interrupt signal in this variable so when we get the interrupt signal
461061da546Spatrick   // as the sole reason for the process being stopped, we can auto resume
462061da546Spatrick   // the process.
463061da546Spatrick   bool m_did_exec;
464061da546Spatrick 
465061da546Spatrick   void *(*m_dyld_process_info_create)(task_t task, uint64_t timestamp,
466061da546Spatrick                                       kern_return_t *kernelError);
467061da546Spatrick   void (*m_dyld_process_info_for_each_image)(
468061da546Spatrick       void *info, void (^callback)(uint64_t machHeaderAddress,
469061da546Spatrick                                    const uuid_t uuid, const char *path));
470061da546Spatrick   void (*m_dyld_process_info_release)(void *info);
471061da546Spatrick   void (*m_dyld_process_info_get_cache)(void *info, void *cacheInfo);
472061da546Spatrick   uint32_t (*m_dyld_process_info_get_platform)(void *info);
473*f6aab3d8Srobert   void (*m_dyld_process_info_get_state)(void *info, void *stateInfo);
474061da546Spatrick };
475061da546Spatrick 
476dda28197Spatrick #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H
477