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