Processes & Concurrency

RSS for tag

Discover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.

Concurrency Documentation

Posts under Processes & Concurrency subtopic

Post

Replies

Boosts

Views

Activity

Subprocess ownership and timeout recovery on Intel macOS Monterey
Hi Quinn, Following your recommendation by email, I’m posting this as a new thread. Thank you again for your guidance on Virtualization.framework. This is a separate question about ordinary host-side subprocess ownership and timeout recovery, not VM cleanup. Target environment: Intel x86_64 macOS Monterey 12.7.6, build 21H1320 Python 3.13.15 Public, supported mechanisms; no root privileges, private APIs or kernel extensions We are verifying a subprocess supervision component with this process structure: Trusted caller process → runner → pytest → private helper → native subprocess Each parent normally owns the consuming wait for its direct child. The private helper exclusively manages signalling and reaping of its native child. Outer processes do not signal saved helper/native PIDs. Cancellation is cooperative, through channels and file/token delivery. The runner observes its fresh pytest child, drains stdout/stderr with bounded retention, and consumes its exact child’s status after exit is observed. The runner, pytest and helper are launched in separate sessions. Consequently, signalling pytest’s process group would not cover the separately sessioned helper and its native child. The unresolved failure case is: A fresh pytest invocation starts. Cancellation delivery fails, or delivery succeeds but the work does not finish. The runner continues observation and bounded output draining within the remaining deadline. The deadline expires while pytest or processes below it may still be alive. The runner reports an unresolved outcome and may exit. The caller also has a bounded deadline and may return without consuming its runner child. Closing capture pipes can cause EPIPE and disturb the child’s cleanup. Exiting a consuming parent also relinquishes its ability to collect that child’s eventual status. The outer caller does not automatically acquire wait rights over pytest or its descendants. Our current policy retains affected files, preserves the original failure, and prevents subsequent tests from starting. We do not treat cancellation delivery, pipe EOF, successful signal delivery, or direct-child reap as proof that every descendant has stopped. This prevents false success, but does not resolve responsibility for work that remains alive. We have considered separating the caller’s response lifetime from the consuming owners’ lifetimes: the caller could return an unresolved response while both existing parents remain alive, draining output and collecting their direct children later. However, keeping them alive adds no termination authority and does not address a crash of either owner. I am not asking for an absolute guarantee against arbitrary kernel failures, or a promise that SIGKILL always completes within a fixed time. I would like to understand the supported architectural approach on Monterey. My questions are: Is retaining the existing consuming parents beyond the response deadline the appropriate pattern, or is there a supported macOS facility that provides a better ownership and recovery boundary? What safe termination authority should those owners retain over their fresh direct children? If process groups are part of the solution, what lifecycle rules are needed to avoid acting on a reused identifier, particularly after leader exit or reaping? Is there a supported way to manage the separately sessioned helper/native work if an intermediate parent exits? Or must each level independently retain its own supervision and cleanup responsibility? If the consuming owner itself crashes, is there a supported recovery mechanism for ordinary subprocesses? Would launchd or XPC materially help, and what limitations would remain for descendants in separate sessions? Which design constraint would you recommend changing: cooperative-only cancellation, the fixed lifetime of the runner, or the process topology? These are our current choices, not restrictions we assume macOS imposes. Our practical goal is a bounded response while an identifiable owner remains responsible for unsettled work, with appropriate termination authority and an honest unresolved outcome when cleanup cannot be established. The immediate qualification scope is only three simple tests, using shell bodies such as exit, kill -9 $$, and echo with ordinary exit statuses. They contain no intentional background work, pipelines or command substitutions. We would prefer a proportionate supported pattern rather than a new general supervision framework. If a reduced example would help clarify the question, I can provide one. Thank you for your time and guidance.
6
0
171
3w
Diagnosing pre-main latency in a short-lived macOS child process while preserving its parent
I’m looking for a supported way to investigate startup latency before main() in a short-lived native macOS child process, while preserving its original parent-child relationship. Environment macOS 26.6.2, build 25G83. Native arm64 executables. The on-disk /usr/lib/dyld contains the identifier dyld-1387; this is a static observation, not independent verification of all runtime shared-cache components. The diagnostic runs were started manually from normal macOS Terminal. All inputs and target processes are synthetic test fixtures. Execution structure Test supervisor → Watchdog → Observer → Query Observer launches Query using posix_spawn(). Query checks a synthetic target process’s identity using Security.framework and produces a fixed 28-byte result. Observer passes an explicit environment containing only LANG=C and LC_ALL=C. Consequently, exporting DYLD variables in the outer Terminal would not pass them to Query. Our existing test has a 1000 ms Query deadline and requires empty Query stderr. This is an application-defined acceptance requirement, not a claimed macOS timing guarantee. Observed results A historical full regression run timed out at approximately 1001 ms, with no Query result bytes received. That run did not have main-entry instrumentation, so we cannot determine where its time was spent. A later isolated, instrumented run measured: posix_spawn return to Query main entry: 832.687 ms main entry to return: 24.179 ms Observer-measured Query elapsed time: 864 ms Another isolated, instrumented run measured: posix_spawn call duration: 0.179 ms spawn return to main entry: 634.334 ms main entry to return: 6.757 ms Observer-measured Query elapsed time: 647 ms In the third run, getrusage(RUSAGE_SELF) at main entry reported cumulative CPU time of 3.014 ms user and 2.583 ms system. Before main returned, the cumulative total was 8.088 ms. Timeline measurements used CLOCK_MONOTONIC. Interpretation limits These successful diagnostic runs do not explain or resolve the historical timeout. Instrumentation changes the executable, and cache state and scheduling may differ. The CPU and wall-clock measurements cover different intervals. Subtracting them would not give an exact waiting-time measurement. We cannot currently attribute the delay to dyld, scheduling, security checks, IPC, or I/O. Diagnostic constraints We want to preserve the original parent-child relationship and avoid system-wide collection, disabling security protections, or silently changing permissions. We have not established that the Instruments App Launch configuration available to us can capture this child’s earliest startup phases while restricting collection to Query. The historical DYLD_PRINT_STATISTICS options are not documented in the installed dyld manual. Attaching a sampling tool after obtaining the PID may miss the relevant startup interval and may perturb this short-lived process. Questions What supported tool or API on this macOS version can distinguish startup phases before main() for this posix_spawn-created child? Can collection itself be restricted to Query, rather than collecting system-wide data and filtering the report afterward? What permissions are required, which early phases remain unobservable, and how much observer perturbation should we expect? If these constraints cannot all be met, what is the smallest necessary change to the diagnostic setup? What minimal sample project and evidence would be most useful for further investigation? I have preserved the original failure and subsequent diagnostic evidence, but do not yet have a standalone Xcode sample that reliably reproduces the historical timeout. I’m requesting guidance on an appropriate measurement method, not asserting that this is a confirmed macOS defect.
4
0
177
3w
macOS XPC: Can incoming message size be bounded before payload allocation?
Hello, I'm designing a local macOS helper service (minimum deployment target: macOS 13) that performs one fixed syntax-validation operation. The submitted source is never executed. The security contract requires: A maximum incoming transport request size of 327,680 bytes. Immediate rejection when the 327,681st byte is encountered, without an allocation proportional to an unbounded sender-controlled payload. No application-level response for an oversized transport request, followed by termination of the affected connection. Complete application responses limited to 65,536 bytes, without treating truncated output as successful. I've reviewed the public XPC APIs, including xpc_data_get_length, xpc_connection_cancel, and xpc_connection_set_peer_code_signing_requirement. The remaining uncertainty is whether XPC can enforce a receiver-side message-size limit before materializing the incoming payload. My questions are: Does any public XPC API on macOS 13+ provide a documented maximum incoming message size that is enforced before payload materialization or proportional allocation? If not, is the entire incoming XPC message necessarily materialized before the application event handler receives it? Is there a supported XPC design for guaranteeing bounded receiver memory with untrusted input, or should this requirement use a different local transport, such as an AF_UNIX SOCK_STREAM socket? What guarantees does xpc_connection_cancel provide regarding connection termination, pending messages, and prevention of connection reuse after detecting malformed or oversized input? I'm specifically looking for documented platform guarantees rather than behavior that happens to work in testing. Thank you!
4
0
317
3w
Supported libSystem state after a LaunchDaemon permanently drops privileges
I am testing a fixed signed LaunchDaemon startup program that uses setgroups, setgid and setuid to establish a dedicated non-root identity before loading its service library or creating an application XPC listener. This follows the single-process, deferred-library direction discussed in DTS thread 844906. The remaining question is the supported treatment of system-runtime state initialized before the credential transition. Test environment: Apple silicon, macOS 27.0.1 / Darwin 27.0.0, hardened runtime, no special entitlements. The host links only libSystem and has no application constructors. This is a temporary diagnostic, not an installed product or a file-operation service. Our test verifies real, effective and saved UID/GID, the exact supplementary group vector and failed attempts to regain root. After the transition, a read-only own-task Mach inventory still sees a voucher even though successful task/current-thread voucher getters return null. It also sees one send+receive endpoint without an alias to any of the queried special/registered roles. Ordinary hardened launchd controls in both the login GUI and user domains also have a voucher and such an endpoint. Their recorded endpoint attributes match the post-drop test: empty queue, sequence 1, make-send count 1, send rights present, no send-once rights, port sets or notification requests. We do not treat this as proof that the objects or authority are equivalent. No messages are sent to the unidentified endpoint and no runtime-owned rights are destroyed. In a separate ordinary-user test, public voucher recipe extraction reports only a BANK attribute. Published libdispatch source describes a default task-bank voucher stored separately from the current thread's voucher slot. Published XNU source captures identity when bank context is initialized. We have not established the corresponding lifecycle or authority implications on this OS release, and do not claim that the observed voucher retains root authority. For this startup arrangement, what supported public contract should an application use to establish that libSystem's retained runtime context does not preserve usable pre-drop administrator authority before loading service code? Is there a supported sanitization step, or a specific documented OS trust assumption under which leaving that state intact is intended? If the combination of exact group reduction, deferred service loading and launchd Mach-service check-in cannot support that boundary, which public architecture should we use instead? We are seeking a documented arrangement or a clear limit on the guarantee, rather than a private reset API or an explanation of every internal endpoint. We have not used same-PID exec, a root supervisor, private APIs, or a broad port-type allowlist. Relevant documentation or a minimal public sample would help.
1
0
352
3w
macOS 14+: Safely supervising worker-created child processes.
Hello Apple Developer Community, We are developing a macOS application with a minimum deployment target of macOS 14.0. We are investigating a process-supervision safety problem involving the following topology: Root → Worker → Child The Worker creates the Child using native process APIs and is responsible for supervising its lifecycle. The critical failure scenario Worker successfully creates Child. Child exists, but its verified process identity has not yet been communicated to Root. Worker unexpectedly terminates before completing the identity handoff. Root must avoid signaling an unrelated process while ensuring that an untracked Child cannot continue executing without authorization. Our safety requirements Independently establish Child's exact process-lifetime identity. Prevent unsafe process signaling caused by PID reuse. Handle Worker failure before identity handoff. Verify process termination and disposition. Avoid relying on private APIs or restricted entitlements. Maintain compatibility with macOS 14 and later. What we have investigated We have reviewed posix_spawn, waitpid, process observation APIs, audit-token-based process identification and signaling, Endpoint Security, and launchd-based supervision. We understand that Endpoint Security FORK events are notifications rather than authorization events, and that dropped notifications may prevent complete birth tracking. We also found es_new_descendants_client in the macOS 27 SDK, but it requires an Endpoint Security entitlement and does not meet our current macOS 14 deployment requirements. We understand that a process cannot automatically use waitpid to reap a grandchild merely because the intermediate parent has terminated. Our questions Is there a publicly supported macOS 14+ API or process-supervision mechanism that can reliably establish the identity of a Worker-created Child even if Worker terminates before communicating that identity? Is there a supported approach for safely containing such a Child when its identity is not yet known to Root? Can audit-token-based signaling provide sufficient process-lifetime identity guarantees for this scenario, and what minimum macOS version supports the relevant APIs? Is there a supported mechanism for independently verifying Child termination when Root is not its direct parent? If this cannot be guaranteed using public APIs, would Apple recommend changing the architecture so that Root directly creates and supervises Child? We are not requesting private API access or Endpoint Security entitlements. We would appreciate guidance on the supported macOS process-lifecycle contracts before proceeding with implementation. Thank you for your assistance.
5
0
604
3w
C-XPC on macOS 14: Do connection EUID/ASID and message-derived SecCode identify the same sender?
Platform / environment Minimum deployment target: macOS 14.0. Development environment: macOS 26.3, Xcode 26.6, macOS SDK 26.5, Swift 6.3.3. We are evaluating public C-XPC and Security.framework APIs; we have not yet validated this identity model over a real C-XPC connection. Context A per-user, signed Runtime Host accepts a connection from a separately signed client. Let peer be the accepted C-XPC peer connection, and receivedMessage the original request dictionary delivered by that connection's event handler. Our admission policy requires both (a) the effective UID and audit session of the actual message sender and (b) validation of that sender's dynamic code against an independently configured code-signing requirement. No application-level authority is granted before these checks. API sequence under review We would first read xpc_connection_get_euid(peer) and xpc_connection_get_asid(peer), then obtain a dynamic code reference via SecCodeCreateWithXPCMessage(receivedMessage, kSecCSDefaultFlags, &code). We would validate that reference with SecCodeCheckValidity(code, kSecCSDefaultFlags, approvedRequirement), where approvedRequirement is configured independently of the peer, and finally inspect the required signing information with SecCodeCopySigningInformation. Reading signing information is not a substitute for code validation. Question On macOS 14, is there a documented, supported guarantee that the connection-level EUID/ASID and the message-derived SecCode refer to the same process occurrence and the actual sender of this particular received request? The connection getters describe attributes captured when the connection was established, while SecCodeCreateWithXPCMessage derives a dynamic-code reference from the original received XPC dictionary. We do not assume that these APIs provide an atomic identity snapshot or prove that their observations refer to the same sender process instance. In particular, what are the limits of any such guarantee when messages or messaging capabilities are forwarded, a process calls exec, a process exits or is replaced, credentials or audit sessions change, or a connection is interrupted and re-established? What if the sender's state changes between message reception and completion of the validation sequence? Request for a supported alternative If this API sequence does not establish that correspondence, which public APIs available on macOS 14 can provide the effective UID, audit session ID, and dynamic-code identity from the same received-message provenance? We are not considering PID-only lookup, private audit-token access, or caller-supplied identity claims. A clarification that the requested guarantee is unavailable would also be valuable. References xpc_connection_get_euid xpc_connection_get_asid Apple DTS: Validating Signature Of XPC Process
0
0
116
4w
Supported completeness and lifecycle guarantees for es_new_descendants_client
Hello Apple Developer Technical Support, I am evaluating es_new_descendants_client for a local command runner that must report success only after its workload and every process descended from that workload have exited. If observation is incomplete or ambiguous, the runner must report failure. This is a design inquiry, not a report of a reproduced operating-system defect; no entitled prototype has been tested. The proposed observer would create its client and subscribe to lifecycle notifications before launching any workload. It would maintain a registry using process-lifetime identities, add processes on creation and remove them on exit. An unmatched event, missing required field, detected loss or observer failure would invalidate the run. It would consider closure only after all registered workload processes had exited. We have not established that these rules are sufficient. Could you clarify which of the following properties are supported API guarantees, and identify any that applications must not rely on? A documented reference or an explicit statement that a guarantee is unavailable would both help. Please identify applicable macOS/SDK versions and any known version-dependent limitations. 1. Membership and creation-event coverage Does the observed subtree retain a process and all of its future descendants after its original parent exits, it is reparented, it double-forks, or it changes process group/session with setpgid or setsid? Could a process remain observable for exit while creation events for its children become invisible? For a workload launched after successful subscription, does every successful process-creation path—including fork, vfork and posix_spawn—produce a lifecycle event sufficient to register the new process before closure can be declared? Which event and identity fields should be used for each path, including a child that exits without a successful exec? Does the calling observer receive the necessary event for its own initial workload launch? 2. Ordering and the meaning of exit Is there a supported per-client ordering guarantee that every child-creation event from a process is delivered before that process's exit notification, including concurrent creation and exit? Can the child's events arrive before the event that introduces that child? Please distinguish kernel enqueue order, handler delivery order and any processing order the application must impose. At what lifecycle boundary is ES_EVENT_TYPE_NOTIFY_EXIT generated? Does it establish that the identified process can no longer execute or initiate writes, or can relevant activity continue after the notification? We would not equate process exit with filesystem durability or completion of work already delegated to other processes. 3. Muting and other visibility filters Does a newly created descendants client have default process, path or target-path mutes that can suppress fork/exit notifications? What supported sequence of configuration and inspection calls establishes complete lifecycle visibility before launch, including mute inversion and executable-path changes? Apart from subscription and muting, are there policy, security, rate-limit or client-type exclusions that can suppress those events? Which suppressed events, if any, are intentionally absent from the sequence counter rather than reported as drops? 4. Sequence numbers and loss detection The global_seq_num documentation requires message version greater than 4. Is that field guaranteed for descendants-client lifecycle messages? Do notifications concerning the calling observer and its descendants use the same per-client sequence? How can a client establish a valid initial baseline and detect loss before its first received message? Is every dropped subscribed, unmuted lifecycle event reflected in the next delivered sequence number? What counter reset, wraparound or client-recreation rules must be handled? Would the proposed registry rule make terminal loss fail safely—for example, a lost final exit leaves a process registered—under the supported ordering and visibility semantics? Or is there a counterexample in which the registry can become empty while an unobserved descendant survives? 5. Synchronization, observer failure and delegated work Does es_sync_client provide any loss/completeness information beyond draining preceding queued messages? Its documented callbacks also run for a destroyed or null client, so we would not interpret callback arrival alone as successful completion. Is there a supported mechanism to distinguish a healthy drain from invalidation? What does “instigates” cover for this client? In particular, can it observe or attribute work executed by existing launchd/XPC services, or by unrelated processes receiving file descriptors? We would treat such work as outside a lineage-only closure claim unless it is explicitly covered or independently excluded. Does this client provide any supported protection against a same-UID workload stopping, killing or otherwise interfering with its observer, or must that isolation be supplied separately? Observer failure would invalidate the run; we are not assuming ES supplies a write barrier for evidence files. 6. Supported cleanup and deployment Is there a supported public mechanism to signal a non-child descendant by process-lifetime identity, without a PID-reuse race between observing it and sending a signal? Is there a recommended approach if the observer cannot wait on that process? We do not want to depend on private libproc functions as an application contract. Finally, is this use case eligible for com.apple.developer.endpoint-security.client in a standalone signed command-line observer, and what supported signing/provisioning or packaging requirements apply? This is a request for guidance, not an entitlement application. Our central question is whether supported APIs can establish complete descendant-process closure under these constraints. If they cannot, we would appreciate a clear statement of that limitation or a supported alternative. Thank you. Documentation consulted: es_new_descendants_client es_sync_client global_seq_num es_process_t
6
0
909
Oct ’26
XPCSession.cancel does not immediately cancel
I'm using an XPCSession to send a message to a service/agent. When calling session.cancel(reason: "stop") the connection is not immediately canceled. The session seems to wait for any pending replies from the service. According to the docs for XPCSession.cancel: When you cancel a session, it discards any unsent messages and invalidates its connection. If there are messages awaiting replies, the session calls the reply handlers with an appropriate XPCRichError. This does seem to imply that messages waiting for replies are immediately canceled, however that's not the case. The service may be busy and may take a while to respond, or it may not reply at all. The session is only canceled after all enqueued messages get a reply from the service. let session = try XPCSession(xpcService: "com.example.listener", cancellationHandler: { print("client session canceled") }) try session.send("Test", replyHandler: { reply in print("reply", reply) }) print("cancel") session.cancel(reason: "cancel") // calls cancellationHandler *after* receiving reply Is that expected behaviour? If the service does not respond at all the XPCService will never be canceled. Compared to xpc_connection_create + xpc_connection_cancel(connection) this does seem to immediately cancel the connection and call the reply_handler and event_handler. This does not wait for pending replies from the service. Is there an alternative way to force cancel an XPCSession? Main goal is to protect against two potential issues: The service is busy and doesn't respond in time. The client fires a timeout and wants to disconnect/reconnect, but the cancellationHandler is not called until service responds. So the timeout is not useful, client needs to wait for a reply anyway. The service does not respond at all. This could for example happen if a Launch Agent is improperly configured. The mach service is registered, but the agent may not launch. Sending a message on the XPCSession will never receive a reply.
3
0
235
Oct ’26
Sandboxed helper keeps running after the app is turned off in Background App Activity
Short version: we run a sandboxed helper as a hidden service account, started at boot by an SMAppService daemon. It works, even before login. But when the user turns our app off in Background App Activity, only the daemon stops. The helper keeps running. Is this setup supported, and what's the right way to manage the helper? What we want A Developer ID signed, notarized app (not Mac App Store) with a helper that parses untrusted input. The helper should: run as a dedicated, hidden, non-login local account; use App Sandbox, with its own container; be available before anyone logs in (after FileVault unlock). What we built An unsandboxed root LaunchDaemon, registered with SMAppService.daemon, runs this at boot: launchctl bootstrap user/<serviceUID> <fixed-agent-plist> The agent plist uses LimitLoadToSessionType=Background. The helper is a nested app in the same bundle, with com.apple.security.app-sandbox=true. We don't create a GUI session, change UID after the sandbox starts, or use private APIs. What we measured macOS 27.0 (26A428), arm64, dummy data only: Register and approve: the daemon starts. The helper starts as UID 60000, its container works, and reads outside it are denied. Turn the app off in Background App Activity: the daemon gets SIGTERM and stops. The helper keeps running (same PID). Turn it back on: the daemon starts again. Its bootstrap returns exit 5, because the old helper is still loaded. Call unregister(): the daemon stops. The helper keeps running. Cold boot (tested with a plain /Library/LaunchDaemons job, not yet SMAppService): the helper started and worked before login finished. For comparison, running the same sandboxed helper as a system daemon with UserName set to this account fails before main: Incoming message euid:60000 does not match secinitd uid:0. Questions Is this setup supported for shipping, including the sandbox starting before anyone logs in? Does the approval for daemon-bundled helpers cover a helper bootstrapped into another account's domain? Our plan: when the daemon gets SIGTERM, it runs bootout on the helper and its domain, and it treats bootstrap exit 5 as "already loaded". Is that the intended pattern, or is there a supported way for the helper to follow the app's Background App Activity setting? If this setup isn't supported, what public mechanism gives a sandboxed helper its own non-root identity before login? I can share the plists, entitlements and logs from a minimal reproducer.
6
0
679
Oct ’26
AlarmKit custom LiveActivityIntent: can executions overlap or be redelivered across app relaunch?
Hello, I'm developing an iPhone alarm app with AlarmKit. The alert has a custom secondary button whose intent conforms to LiveActivityIntent, declares supportedModes: .background and authenticationPolicy: .alwaysAllowed, and passes an alarm ID to app code from a @MainActor perform() implementation. The intent lives in the app target. It is not shared with a widget or an App Intents extension. The operation persists an in-progress record, awaits scheduling a new alarm, cancels the original only after scheduling succeeds, and then persists completion. After an interruption or relaunch, recovery reads the persisted original and candidate IDs and checks the system's alarm inventory. I want to understand which execution guarantees the app can rely on, so that recovery never schedules a duplicate alarm or cancels a valid candidate. I've read the LiveActivityIntent and App Intents runtime documentation. I understand how execution placement and foreground/background modes are described, but I couldn't find a public guarantee about overlap or redelivery when the app process is replaced. To be clear, I have not observed two simultaneous processes or duplicate execution in this setup. This is a question about what the app may assume, not a bug report. Questions For this app-target LiveActivityIntent configuration on iOS/iPadOS 26.x, can an older process of the same app still be executing an alarm-button intent while a newly launched process begins another invocation? Is there a documented single-process or handover guarantee an app may rely on? I'd appreciate it if the answer could distinguish multiple concurrent invocations within one process from overlap between an old and a newly launched process. Can the same alarm-button action be redelivered after an interruption or relaunch, including after perform() has thrown or returned? Which serialization or at-most-once guarantees, if any, apply to invocations for the same alarm ID, and which duplicate-delivery defenses must the app provide? I'm not assuming that every invocation comes from a new user tap. If the process that issued an AlarmKit scheduling or cancellation request terminates, may the app assume that the request has either completed or been abandoned before a newly launched process calls AlarmKit? If not, which public API checks or sequencing are recommended before recovery modifies the original or candidate alarm? I'm looking for supported app-level assumptions and recommended safeguards, not internal process lifecycle details. The app must preserve valid alarms and must never report an uncertain result as success. The shipping target is iPhone, with a minimum deployment target of 26.1. Earlier isolated testing on an iPad (9th generation, including iPadOS 26.7) did not show the overlap described above. Related question about the alert presentation after an intent error: [https://developer.apple.com/forums/thread/849075] Thank you!
0
0
348
Oct ’26
Supported macOS design for safely terminating an app-owned helper subtree?
I am designing a bounded local diagnostic helper for macOS. It would run only purpose-built helpers supplied by the application, not third-party or untrusted code. The design question is how to stop exactly those helpers and their descendants on timeout, without affecting an unrelated process or incorrectly reporting that cleanup is complete. This is a public-API suitability question, not a report of a reproduced macOS bug. The intended diagnostic is not an antivirus or endpoint-detection product. The required properties are: Identify each owned process by its lifetime and association with this helper run, not a numeric PID or process-group ID alone. Account for descendants across fork/exec, parent exit or reparenting, and process-group/session changes. Observing that a descendant escaped is not equivalent to preventing an escape. Terminate only the still-owned processes without a stale-identity race between checking ownership and signaling. Report completion only when all owned descendants have stopped and no new owned descendants can appear. Leader exit, IPC disconnection, or an unauthenticated empty process list would not be sufficient. Lost events or uncertain membership must leave the outcome inconclusive. Which supported public API or service/containment architecture can provide these properties? If they cannot all be guaranteed, which constraint should be changed and what guarantee can the supported alternative actually provide? I have reviewed the documentation for es_new_descendants_client and es_sync_client. The remaining questions are: Is a descendant-scoped Endpoint Security client appropriate for this non-security-product diagnostic? If so, which documented entitlement and packaging route applies? I am asking about eligibility, not assuming it. Does any supported design combine lifetime-safe control with containment of the whole owned subtree, including concurrent descendant creation? Merely receiving events would not establish that property. What additional protocol, if any, makes a synchronization callback sufficient to establish complete termination when client destruction, event loss, and concurrent activity are possible? I am not treating that callback alone as proof that no owned process remains. I can redesign around a helper that cannot create descendants if that is the supported approach. In that case, what supported mechanism enforces that restriction and what termination guarantees remain? So far, a standalone C harness has passed eleven fabricated-input cases with assertions enabled. It exercised no Endpoint Security client, process-tree creation/enumeration/control, or application behavior. It is not a runtime reproducer for this API-design question and does not establish native lifecycle safety. Pointers to documented guarantees, limitations, or an Apple sample would help me choose the architecture before preparing a narrowly scoped native test. I am not seeking private APIs or a way to disable platform protections. No logs, source archive, or binary is attached.
1
0
543
Sep ’26
Supported macOS confinement for a supervised process tree
I am evaluating a local diagnostic design before implementation or deployment and need to identify a public, supported macOS confinement mechanism. Proposed arrangement: A privileged custodian remains outside a separate privileged guardian's process group. The guardian launches a fixed diagnostic parent under a dedicated unprivileged identity. That parent sequentially launches three fixed sandboxed Python workloads, one child at a time. The current termination design targets the guardian's process group. It must not rely on whole-host process scans or indiscriminate killing. The proposed sandbox profiles are allow-default with file/network restrictions; the test-child profiles deny process-fork. We have not established that these restrictions prevent an existing process from changing its own group or session. Is there a public, supported interface or configuration that keeps all workload descendants within the supervisor's termination boundary from the initial child transition through final cleanup, while still allowing the parent to launch its authorized sequential children? In particular, please clarify: Escape through setsid/setpgid, spawn attributes, exec or native-library paths. When enforcement begins and whether descendants can relax it. Behavior when the diagnostic parent or guardian exits. Required privileges, entitlements, and supported OS/SDK versions. If the described sandbox categories do not establish that property, please identify the supported alternative boundary, if one exists. A different boundary would require an explicit design change on our side. I am requesting documented interface behavior and limitations—not private sandbox internals, a review of project code, or an absolute termination guarantee during kernel failure. No experiment has been performed to establish this property.
0
0
255
Sep ’26
Supported lifecycle and termination guarantees for an embedded macOS XPC service
We are evaluating a lifecycle architecture for a local macOS application and would appreciate guidance on supported public APIs. Proposed architecture: A normally signed, non-root host application. One embedded XPC service with exactly one intended client. No application-created subprocesses inside the service. No privileged helper, persistent LaunchAgent, exported endpoints, private APIs, or reduced system security. One bounded operation per session. Failed or interrupted operations must not automatically be retried. Initial validation would use synthetic workloads only. Our current evaluation target is macOS 15.6 on Apple silicon, using the macOS 15.5 SDK. Please identify any relevant deployment-version limitations. The XPC overview (https://developer.apple.com/documentation/xpc) describes an embedded service as tied to its client's lifetime. We also understand that xpc_connection_cancel (https://developer.apple.com/documentation/xpc/xpc_connection_cancel(_:)) is asynchronous and non-preemptive; we are not treating connection cancellation as proof of service termination. We need clarification on these points: Client death and service startup Does the documented client-lifetime relationship cover client termination, including SIGKILL, during service startup before the first reply? Does it also cover an already running service that is blocked or stopped with SIGSTOP? Which behavior is guaranteed, and which timing or failure cases are intentionally unspecified? Timeout while the client remains alive What supported public mechanism should a normal application use to terminate its own unresponsive embedded service when an operation exceeds its deadline? We want to avoid PID enumeration, PID-reuse races, broad process-group signaling, and exporting a full task-control port. Is there a supported identity-bound termination mechanism? If not, what architecture does Apple recommend? A stopped or hung client remains alive, so we do not assume client-lifetime coupling handles that separate failure case. Observing termination Which public notification reliably identifies the exit of the particular service instance, as distinct from connection invalidation or a missing reply? Because launchd is the parent, the application cannot simply waitpid the service. Is reaping entirely launchd's responsibility, and what completion claim can the application legitimately make? Identity and required privileges Which public signing requirements, launch constraints, sandbox settings, or entitlements are necessary for this architecture? Please distinguish authentication before accepting work from constraints enforced before service code executes. We do not assume peer authentication also grants termination rights. Restart behavior After interruption, cancellation, client exit, or service failure, under what circumstances can launchd or subsequent XPC activity start a replacement service? What supported pattern prevents accidental resubmission or resumption of the same failed operation? We are not asking for hard real-time guarantees during kernel failure, or claiming that forced termination proves callback completion or explicit memory zeroization. If this combination of requirements is unsupported, identifying that boundary and the smallest supported architectural alternative would be a useful answer. Documentation references or a minimal public sample would be welcome.
3
0
346
Sep ’26
macOS 27 - my faceless bg-only app now appears in the Dock - how to get rid of that?
My macOS app Find Any File contains another app inside its Resources folder. It's a background-only app that checks if the user presses a hotkey, in which case it launches my app. Since macOS 27, when the hotkey app is running, it appears in the Dock with a "Running in Background" subtitle. That's totally not wanted. How do I make it not appear in the Dock? I've got both "LSBackgroundOnly" and "LSUIElement" set to true in the Info.plist, to no avail.
3
0
357
Sep ’26
[27.0beta] Wrong app shown as running in Background in Dock
I develop a tool on macOS which is composed of an UI app to manage the main app settings, and an Agent that runs in background doing some tasks ? (Running the agent is optional, can be launched from the UI app, and can be launched by macOS at startup with SMAppService. ) Agent has the LSUIElement flag set, and only shows a Menu Extra (or whatever it now named), and sometimes some notifications. The whole App package is bundled this way MainAppUI.app/Contents/Library/LoginItems/AppAgent.app (for SMAppService to work) This has been working correctly for years Now on macOS 27 beta, once I quit the UI App, having launched the Agent, the Dock reports the UI App is still running in background (with the grey dot) . But only the Agent is running, not the UI app process. Moreover, System Settings->Background apps reports both the UI app AND the Agent as both requesting to run in background. I would have expected only the Agent being listed in System Settings, and nothing appearing in the Dock. Is this a bug in the OS beta , showing the top-level container bundle as the app running in background instead of the executable direct container ? Or maybe it's on me and I should bundle my app differently ? (I cannot "reverse" the bundle and put the Agent as the main app, with UI "inside", as double clicking the main app should launch the UI App , not the Agent. ) BTW, filed FB23203848 for the same subject. thanks for any direction
3
1
1.2k
Sep ’26
Crashe__CFRunLoopServiceMachPort.cold 96% Foreground
Hello, we have encountered a large number of __CFRunLoopServiceMachPort.cold crashes on iOS 26. These crashes frequently occur when the app transitions from the background to the foreground or is launched after sitting idle for a period of time. Despite extensive analysis, we have been unable to find a solution. Currently, the crash data indicates that this issue is specific to iOS 26. We would greatly appreciate your assistance. Thank you very much! Hardware Model: iPhone18,1 OS Version: iPhone OS 26.5.2 (23F84) Release Type: User Baseband Version: 1.60.02 Crash Reporter Key: fda96a4036dcb83e124660e11b654c9484b81dae Incident Identifier: EF18C4DD-7624-42D0-BA72-F17BBC263B16 Time Awake Since Boot: 2900000 seconds Triggered by Thread: 0, Dispatch Queue: com.apple.main-thread Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x00000001917d316c Termination Reason: Namespace SIGNAL, Code 5, Trace/BPT trap: 5 Terminating Process: exc handler [82210] Application Specific Information: (ipc/rcv) invalid name Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 CoreFoundation 0x1917d316c __CFRunLoopServiceMachPort.cold.1 + 64 1 CoreFoundation 0x19168a444 __CFRunLoopServiceMachPort + 416 2 CoreFoundation 0x191654310 __CFRunLoopRun + 1188 3 CoreFoundation 0x19165354c _CFRunLoopRunSpecificWithOptions + 532 4 GraphicsServices 0x236df7498 GSEventRunModal + 120 5 UIKitCore 0x19734c244 -[UIApplication _run] + 796 6 UIKitCore 0x1972b7158 UIApplicationMain + 332 7 KMMVideo 0x1047fe24c 0x104304000 + 5218892 8 dyld 0x18e261c1c start + 6928 Thread 1 name: transmit_hls_7683_193735 Thread 1: 0 libsystem_kernel.dylib 0x2407da5e8 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x1f0852b48 _pthread_cond_wait + 980 2 libc++.1.dylib 0x1a0d5dbcc std::__1::condition_variable::wait(std::__1::unique_lockstd::__1::mutex&) + 32 3 iOSPlayer 0x118cd6114 a_task_runner::worker() + 116 4 iOSPlayer 0x118cd5650 a_task_runner::work_thread() + 196 5 iOSPlayer 0x118cd654c void* std::__1::__thread_proxy[abi:ne200100]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_deletestd::__1::__thread_struct>, void (a_task_runner::)(), a_task_runner>>(void*) + 72 6 libsystem_pthread.dylib 0x1f0854438 _pthread_start + 136 7 libsystem_pthread.dylib 0x1f08508cc thread_start + 8 Thread 2: 0 libsystem_kernel.dylib 0x2407d9ed8 read + 8 1 XLTranscodeKit 0x115bb5f4c runtime.read_trampoline.abi0 + 28 Thread 3: Thread 4: 0 libsystem_kernel.dylib 0x2407da5e8 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x1f0852b48 _pthread_cond_wait + 980 2 XLTranscodeKit 0x115bb6648 runtime.pthread_cond_wait_trampoline.abi0 + 24 3 XLTranscodeKit 0x115bb4fb8 runtime.asmcgocall.abi0 + 200 4 ??? 0xd65f03c0 ??? Thread 5: 0 XLTranscodeKit 0x115b3eb68 */bytealg.IndexByteString + 40 1 XLTranscodeKit 0x115b966b8 runtime.findnull + 104 Thread 6: 0 libsystem_kernel.dylib 0x2407db8dc kevent + 8 1 XLTranscodeKit 0x115bb6398 runtime.kevent_trampoline.abi0 + 40 Thread 7: 0 libsystem_kernel.dylib 0x2407da5e8 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x1f0852b48 _pthread_cond_wait + 980 2 XLTranscodeKit 0x115bb6648 runtime.pthread_cond_wait_trampoline.abi0 + 24 3 XLTranscodeKit 0x115bb4fb8 runtime.asmcgocall.abi0 + 200 4 ??? 0xd65f03c0 ???
3
0
501
Sep ’26
Can an ExtensionFoundation-based extension on macOS have its own extension point and host its own extensions?
It is possible for an extension to an app (based on ExtensionFoundation) to declare its own extension point and host its own ExtensionFoundation extensions? Based on the documentation, I am guessing the answer is no, but worth double-checking. What would be the reason to prevent this? Every ExtensionFoundation extension runs in its own process, and may have need to be extended safely just as its host app does. Thank you!
3
0
416
Sep ’26
Is suspended spawn + audit_token_t matching a supported security boundary for one exact macOS process occurrence?
I’m designing a macOS privileged-service boundary and I’d like to clarify whether a process-occurrence authentication pattern previously described by Apple DTS is a supported shipping security contract, rather than just behaviour that happens to work on current macOS. Target: current macOS 26.x, using public APIs only. Threat model An arbitrary hostile process may run as the same ordinary, non-admin login user as the application. The attacker can launch an exact second copy of the legitimately signed requester binary. The attacker cannot obtain administrator / Touch ID authorization and does not control root, SIP, Recovery, the kernel, or the code-signing infrastructure. Desired property After a fresh Human-authorized operation, a root LaunchDaemon should grant authority to one specific requester process occurrence, not to every process having the same code-signing identity. Apple DTS thread 842442 describes a pattern based on: launching the requester suspended with posix_spawn(..., POSIX_SPAWN_START_SUSPENDED); obtaining a name/task port for that process; reading its TASK_AUDIT_TOKEN; resuming the process; and accepting only Mach messages whose kernel audit trailer identifies that same process occurrence. Thread 842442 also describes this area as being on “thin compatibility ice”, which is why I do not want to build a security boundary on behaviour that Apple does not intend applications to rely on. My core question is: Can a shipping macOS application rely on a pre-bound audit_token_t obtained from a suspended child and compare it against the audit token in subsequent raw Mach message trailers as a supported security boundary for that exact process occurrence? In particular, I need to know whether the supported contract covers: distinguishing another process with the exact same signed executable; PID reuse after the original process exits; messages queued before or around sender termination; a Mach send right transferred to another process — does the receiver see the audit token of the process that actually sends each message?; later exec by the original process; and whether full audit_token_t equality is an appropriate supported comparison for this purpose. If that is not a supported shipping contract, is there a current public XPC API that provides the equivalent property: binding one privileged-service session to one exact process occurrence rather than merely to its code-signing identity? I’m specifically trying to distinguish: code identity = this is an approved executable from mission authority = this one particular authorized process occurrence I’m happy with a negative answer if macOS does not expose a stable public contract for the latter. Related Apple DTS discussion: https://developer.apple.com/forums/thread/842442
11
0
895
Sep ’26
Supported OS-owned lifetime for one-shot macOS work after its controller exits
I’m designing a macOS utility that needs to run a bounded, one-shot diagnostic and collect its result. The lifetime problem is: A controller asks for the diagnostic to start. The diagnostic may begin successfully. The controller can then fail immediately — potentially before it has retained the child’s PID or established output collection. The diagnostic may close stdin/stdout/stderr while continuing to run. The diagnostic must not become an unmanaged orphan if the controller disappears. A focused test case uses Foundation.Process: Controller launches Child. Controller immediately exits with _exit(42), without waiting for Child or retaining its process identifier. Child calls setsid(), closes stdin/stdout/stderr, stays alive for up to 120 seconds, then exits. What I’m trying to establish is the supported macOS lifecycle boundary, rather than inventing a cleanup scheme around PIDs. Is there a supported per-user launchd or other OS-managed mechanism where the OS assumes responsibility for the job before the diagnostic process can start, such that the requesting controller may subsequently fail without leaving an unmanaged process? Specifically: At what point does the OS own the lifetime relative to registration and process creation? What supported mechanism bounds or terminates the job if the requesting controller disappears? Is there a supported hard execution-time limit, rather than an idle-time concept? How are descendants or process groups contained, and does calling setsid() conflict with that containment? What completion or failure information remains available to a later controller after the original requester has died? Are there important per-user, privilege, sandboxing, signing, or macOS-version limitations? I’m not reporting an Apple bug and I’m not asking for a custom recovery implementation. I’m trying to identify the documented supported lifetime mechanism and its guarantees and limitations before choosing an architecture. Environment: macOS 26.6.2 Apple silicon Foundation.Process is used by the focused reproducer Apple Developer Technical Support suggested I start a new thread for this specific question in Processes & Concurrency.
4
0
405
Sep ’26
Subprocess ownership and timeout recovery on Intel macOS Monterey
Hi Quinn, Following your recommendation by email, I’m posting this as a new thread. Thank you again for your guidance on Virtualization.framework. This is a separate question about ordinary host-side subprocess ownership and timeout recovery, not VM cleanup. Target environment: Intel x86_64 macOS Monterey 12.7.6, build 21H1320 Python 3.13.15 Public, supported mechanisms; no root privileges, private APIs or kernel extensions We are verifying a subprocess supervision component with this process structure: Trusted caller process → runner → pytest → private helper → native subprocess Each parent normally owns the consuming wait for its direct child. The private helper exclusively manages signalling and reaping of its native child. Outer processes do not signal saved helper/native PIDs. Cancellation is cooperative, through channels and file/token delivery. The runner observes its fresh pytest child, drains stdout/stderr with bounded retention, and consumes its exact child’s status after exit is observed. The runner, pytest and helper are launched in separate sessions. Consequently, signalling pytest’s process group would not cover the separately sessioned helper and its native child. The unresolved failure case is: A fresh pytest invocation starts. Cancellation delivery fails, or delivery succeeds but the work does not finish. The runner continues observation and bounded output draining within the remaining deadline. The deadline expires while pytest or processes below it may still be alive. The runner reports an unresolved outcome and may exit. The caller also has a bounded deadline and may return without consuming its runner child. Closing capture pipes can cause EPIPE and disturb the child’s cleanup. Exiting a consuming parent also relinquishes its ability to collect that child’s eventual status. The outer caller does not automatically acquire wait rights over pytest or its descendants. Our current policy retains affected files, preserves the original failure, and prevents subsequent tests from starting. We do not treat cancellation delivery, pipe EOF, successful signal delivery, or direct-child reap as proof that every descendant has stopped. This prevents false success, but does not resolve responsibility for work that remains alive. We have considered separating the caller’s response lifetime from the consuming owners’ lifetimes: the caller could return an unresolved response while both existing parents remain alive, draining output and collecting their direct children later. However, keeping them alive adds no termination authority and does not address a crash of either owner. I am not asking for an absolute guarantee against arbitrary kernel failures, or a promise that SIGKILL always completes within a fixed time. I would like to understand the supported architectural approach on Monterey. My questions are: Is retaining the existing consuming parents beyond the response deadline the appropriate pattern, or is there a supported macOS facility that provides a better ownership and recovery boundary? What safe termination authority should those owners retain over their fresh direct children? If process groups are part of the solution, what lifecycle rules are needed to avoid acting on a reused identifier, particularly after leader exit or reaping? Is there a supported way to manage the separately sessioned helper/native work if an intermediate parent exits? Or must each level independently retain its own supervision and cleanup responsibility? If the consuming owner itself crashes, is there a supported recovery mechanism for ordinary subprocesses? Would launchd or XPC materially help, and what limitations would remain for descendants in separate sessions? Which design constraint would you recommend changing: cooperative-only cancellation, the fixed lifetime of the runner, or the process topology? These are our current choices, not restrictions we assume macOS imposes. Our practical goal is a bounded response while an identifiable owner remains responsible for unsettled work, with appropriate termination authority and an honest unresolved outcome when cleanup cannot be established. The immediate qualification scope is only three simple tests, using shell bodies such as exit, kill -9 $$, and echo with ordinary exit statuses. They contain no intentional background work, pipelines or command substitutions. We would prefer a proportionate supported pattern rather than a new general supervision framework. If a reduced example would help clarify the question, I can provide one. Thank you for your time and guidance.
Replies
6
Boosts
0
Views
171
Activity
3w
Diagnosing pre-main latency in a short-lived macOS child process while preserving its parent
I’m looking for a supported way to investigate startup latency before main() in a short-lived native macOS child process, while preserving its original parent-child relationship. Environment macOS 26.6.2, build 25G83. Native arm64 executables. The on-disk /usr/lib/dyld contains the identifier dyld-1387; this is a static observation, not independent verification of all runtime shared-cache components. The diagnostic runs were started manually from normal macOS Terminal. All inputs and target processes are synthetic test fixtures. Execution structure Test supervisor → Watchdog → Observer → Query Observer launches Query using posix_spawn(). Query checks a synthetic target process’s identity using Security.framework and produces a fixed 28-byte result. Observer passes an explicit environment containing only LANG=C and LC_ALL=C. Consequently, exporting DYLD variables in the outer Terminal would not pass them to Query. Our existing test has a 1000 ms Query deadline and requires empty Query stderr. This is an application-defined acceptance requirement, not a claimed macOS timing guarantee. Observed results A historical full regression run timed out at approximately 1001 ms, with no Query result bytes received. That run did not have main-entry instrumentation, so we cannot determine where its time was spent. A later isolated, instrumented run measured: posix_spawn return to Query main entry: 832.687 ms main entry to return: 24.179 ms Observer-measured Query elapsed time: 864 ms Another isolated, instrumented run measured: posix_spawn call duration: 0.179 ms spawn return to main entry: 634.334 ms main entry to return: 6.757 ms Observer-measured Query elapsed time: 647 ms In the third run, getrusage(RUSAGE_SELF) at main entry reported cumulative CPU time of 3.014 ms user and 2.583 ms system. Before main returned, the cumulative total was 8.088 ms. Timeline measurements used CLOCK_MONOTONIC. Interpretation limits These successful diagnostic runs do not explain or resolve the historical timeout. Instrumentation changes the executable, and cache state and scheduling may differ. The CPU and wall-clock measurements cover different intervals. Subtracting them would not give an exact waiting-time measurement. We cannot currently attribute the delay to dyld, scheduling, security checks, IPC, or I/O. Diagnostic constraints We want to preserve the original parent-child relationship and avoid system-wide collection, disabling security protections, or silently changing permissions. We have not established that the Instruments App Launch configuration available to us can capture this child’s earliest startup phases while restricting collection to Query. The historical DYLD_PRINT_STATISTICS options are not documented in the installed dyld manual. Attaching a sampling tool after obtaining the PID may miss the relevant startup interval and may perturb this short-lived process. Questions What supported tool or API on this macOS version can distinguish startup phases before main() for this posix_spawn-created child? Can collection itself be restricted to Query, rather than collecting system-wide data and filtering the report afterward? What permissions are required, which early phases remain unobservable, and how much observer perturbation should we expect? If these constraints cannot all be met, what is the smallest necessary change to the diagnostic setup? What minimal sample project and evidence would be most useful for further investigation? I have preserved the original failure and subsequent diagnostic evidence, but do not yet have a standalone Xcode sample that reliably reproduces the historical timeout. I’m requesting guidance on an appropriate measurement method, not asserting that this is a confirmed macOS defect.
Replies
4
Boosts
0
Views
177
Activity
3w
macOS XPC: Can incoming message size be bounded before payload allocation?
Hello, I'm designing a local macOS helper service (minimum deployment target: macOS 13) that performs one fixed syntax-validation operation. The submitted source is never executed. The security contract requires: A maximum incoming transport request size of 327,680 bytes. Immediate rejection when the 327,681st byte is encountered, without an allocation proportional to an unbounded sender-controlled payload. No application-level response for an oversized transport request, followed by termination of the affected connection. Complete application responses limited to 65,536 bytes, without treating truncated output as successful. I've reviewed the public XPC APIs, including xpc_data_get_length, xpc_connection_cancel, and xpc_connection_set_peer_code_signing_requirement. The remaining uncertainty is whether XPC can enforce a receiver-side message-size limit before materializing the incoming payload. My questions are: Does any public XPC API on macOS 13+ provide a documented maximum incoming message size that is enforced before payload materialization or proportional allocation? If not, is the entire incoming XPC message necessarily materialized before the application event handler receives it? Is there a supported XPC design for guaranteeing bounded receiver memory with untrusted input, or should this requirement use a different local transport, such as an AF_UNIX SOCK_STREAM socket? What guarantees does xpc_connection_cancel provide regarding connection termination, pending messages, and prevention of connection reuse after detecting malformed or oversized input? I'm specifically looking for documented platform guarantees rather than behavior that happens to work in testing. Thank you!
Replies
4
Boosts
0
Views
317
Activity
3w
Supported libSystem state after a LaunchDaemon permanently drops privileges
I am testing a fixed signed LaunchDaemon startup program that uses setgroups, setgid and setuid to establish a dedicated non-root identity before loading its service library or creating an application XPC listener. This follows the single-process, deferred-library direction discussed in DTS thread 844906. The remaining question is the supported treatment of system-runtime state initialized before the credential transition. Test environment: Apple silicon, macOS 27.0.1 / Darwin 27.0.0, hardened runtime, no special entitlements. The host links only libSystem and has no application constructors. This is a temporary diagnostic, not an installed product or a file-operation service. Our test verifies real, effective and saved UID/GID, the exact supplementary group vector and failed attempts to regain root. After the transition, a read-only own-task Mach inventory still sees a voucher even though successful task/current-thread voucher getters return null. It also sees one send+receive endpoint without an alias to any of the queried special/registered roles. Ordinary hardened launchd controls in both the login GUI and user domains also have a voucher and such an endpoint. Their recorded endpoint attributes match the post-drop test: empty queue, sequence 1, make-send count 1, send rights present, no send-once rights, port sets or notification requests. We do not treat this as proof that the objects or authority are equivalent. No messages are sent to the unidentified endpoint and no runtime-owned rights are destroyed. In a separate ordinary-user test, public voucher recipe extraction reports only a BANK attribute. Published libdispatch source describes a default task-bank voucher stored separately from the current thread's voucher slot. Published XNU source captures identity when bank context is initialized. We have not established the corresponding lifecycle or authority implications on this OS release, and do not claim that the observed voucher retains root authority. For this startup arrangement, what supported public contract should an application use to establish that libSystem's retained runtime context does not preserve usable pre-drop administrator authority before loading service code? Is there a supported sanitization step, or a specific documented OS trust assumption under which leaving that state intact is intended? If the combination of exact group reduction, deferred service loading and launchd Mach-service check-in cannot support that boundary, which public architecture should we use instead? We are seeking a documented arrangement or a clear limit on the guarantee, rather than a private reset API or an explanation of every internal endpoint. We have not used same-PID exec, a root supervisor, private APIs, or a broad port-type allowlist. Relevant documentation or a minimal public sample would help.
Replies
1
Boosts
0
Views
352
Activity
3w
macOS 14+: Safely supervising worker-created child processes.
Hello Apple Developer Community, We are developing a macOS application with a minimum deployment target of macOS 14.0. We are investigating a process-supervision safety problem involving the following topology: Root → Worker → Child The Worker creates the Child using native process APIs and is responsible for supervising its lifecycle. The critical failure scenario Worker successfully creates Child. Child exists, but its verified process identity has not yet been communicated to Root. Worker unexpectedly terminates before completing the identity handoff. Root must avoid signaling an unrelated process while ensuring that an untracked Child cannot continue executing without authorization. Our safety requirements Independently establish Child's exact process-lifetime identity. Prevent unsafe process signaling caused by PID reuse. Handle Worker failure before identity handoff. Verify process termination and disposition. Avoid relying on private APIs or restricted entitlements. Maintain compatibility with macOS 14 and later. What we have investigated We have reviewed posix_spawn, waitpid, process observation APIs, audit-token-based process identification and signaling, Endpoint Security, and launchd-based supervision. We understand that Endpoint Security FORK events are notifications rather than authorization events, and that dropped notifications may prevent complete birth tracking. We also found es_new_descendants_client in the macOS 27 SDK, but it requires an Endpoint Security entitlement and does not meet our current macOS 14 deployment requirements. We understand that a process cannot automatically use waitpid to reap a grandchild merely because the intermediate parent has terminated. Our questions Is there a publicly supported macOS 14+ API or process-supervision mechanism that can reliably establish the identity of a Worker-created Child even if Worker terminates before communicating that identity? Is there a supported approach for safely containing such a Child when its identity is not yet known to Root? Can audit-token-based signaling provide sufficient process-lifetime identity guarantees for this scenario, and what minimum macOS version supports the relevant APIs? Is there a supported mechanism for independently verifying Child termination when Root is not its direct parent? If this cannot be guaranteed using public APIs, would Apple recommend changing the architecture so that Root directly creates and supervises Child? We are not requesting private API access or Endpoint Security entitlements. We would appreciate guidance on the supported macOS process-lifecycle contracts before proceeding with implementation. Thank you for your assistance.
Replies
5
Boosts
0
Views
604
Activity
3w
C-XPC on macOS 14: Do connection EUID/ASID and message-derived SecCode identify the same sender?
Platform / environment Minimum deployment target: macOS 14.0. Development environment: macOS 26.3, Xcode 26.6, macOS SDK 26.5, Swift 6.3.3. We are evaluating public C-XPC and Security.framework APIs; we have not yet validated this identity model over a real C-XPC connection. Context A per-user, signed Runtime Host accepts a connection from a separately signed client. Let peer be the accepted C-XPC peer connection, and receivedMessage the original request dictionary delivered by that connection's event handler. Our admission policy requires both (a) the effective UID and audit session of the actual message sender and (b) validation of that sender's dynamic code against an independently configured code-signing requirement. No application-level authority is granted before these checks. API sequence under review We would first read xpc_connection_get_euid(peer) and xpc_connection_get_asid(peer), then obtain a dynamic code reference via SecCodeCreateWithXPCMessage(receivedMessage, kSecCSDefaultFlags, &code). We would validate that reference with SecCodeCheckValidity(code, kSecCSDefaultFlags, approvedRequirement), where approvedRequirement is configured independently of the peer, and finally inspect the required signing information with SecCodeCopySigningInformation. Reading signing information is not a substitute for code validation. Question On macOS 14, is there a documented, supported guarantee that the connection-level EUID/ASID and the message-derived SecCode refer to the same process occurrence and the actual sender of this particular received request? The connection getters describe attributes captured when the connection was established, while SecCodeCreateWithXPCMessage derives a dynamic-code reference from the original received XPC dictionary. We do not assume that these APIs provide an atomic identity snapshot or prove that their observations refer to the same sender process instance. In particular, what are the limits of any such guarantee when messages or messaging capabilities are forwarded, a process calls exec, a process exits or is replaced, credentials or audit sessions change, or a connection is interrupted and re-established? What if the sender's state changes between message reception and completion of the validation sequence? Request for a supported alternative If this API sequence does not establish that correspondence, which public APIs available on macOS 14 can provide the effective UID, audit session ID, and dynamic-code identity from the same received-message provenance? We are not considering PID-only lookup, private audit-token access, or caller-supplied identity claims. A clarification that the requested guarantee is unavailable would also be valuable. References xpc_connection_get_euid xpc_connection_get_asid Apple DTS: Validating Signature Of XPC Process
Replies
0
Boosts
0
Views
116
Activity
4w
Supported completeness and lifecycle guarantees for es_new_descendants_client
Hello Apple Developer Technical Support, I am evaluating es_new_descendants_client for a local command runner that must report success only after its workload and every process descended from that workload have exited. If observation is incomplete or ambiguous, the runner must report failure. This is a design inquiry, not a report of a reproduced operating-system defect; no entitled prototype has been tested. The proposed observer would create its client and subscribe to lifecycle notifications before launching any workload. It would maintain a registry using process-lifetime identities, add processes on creation and remove them on exit. An unmatched event, missing required field, detected loss or observer failure would invalidate the run. It would consider closure only after all registered workload processes had exited. We have not established that these rules are sufficient. Could you clarify which of the following properties are supported API guarantees, and identify any that applications must not rely on? A documented reference or an explicit statement that a guarantee is unavailable would both help. Please identify applicable macOS/SDK versions and any known version-dependent limitations. 1. Membership and creation-event coverage Does the observed subtree retain a process and all of its future descendants after its original parent exits, it is reparented, it double-forks, or it changes process group/session with setpgid or setsid? Could a process remain observable for exit while creation events for its children become invisible? For a workload launched after successful subscription, does every successful process-creation path—including fork, vfork and posix_spawn—produce a lifecycle event sufficient to register the new process before closure can be declared? Which event and identity fields should be used for each path, including a child that exits without a successful exec? Does the calling observer receive the necessary event for its own initial workload launch? 2. Ordering and the meaning of exit Is there a supported per-client ordering guarantee that every child-creation event from a process is delivered before that process's exit notification, including concurrent creation and exit? Can the child's events arrive before the event that introduces that child? Please distinguish kernel enqueue order, handler delivery order and any processing order the application must impose. At what lifecycle boundary is ES_EVENT_TYPE_NOTIFY_EXIT generated? Does it establish that the identified process can no longer execute or initiate writes, or can relevant activity continue after the notification? We would not equate process exit with filesystem durability or completion of work already delegated to other processes. 3. Muting and other visibility filters Does a newly created descendants client have default process, path or target-path mutes that can suppress fork/exit notifications? What supported sequence of configuration and inspection calls establishes complete lifecycle visibility before launch, including mute inversion and executable-path changes? Apart from subscription and muting, are there policy, security, rate-limit or client-type exclusions that can suppress those events? Which suppressed events, if any, are intentionally absent from the sequence counter rather than reported as drops? 4. Sequence numbers and loss detection The global_seq_num documentation requires message version greater than 4. Is that field guaranteed for descendants-client lifecycle messages? Do notifications concerning the calling observer and its descendants use the same per-client sequence? How can a client establish a valid initial baseline and detect loss before its first received message? Is every dropped subscribed, unmuted lifecycle event reflected in the next delivered sequence number? What counter reset, wraparound or client-recreation rules must be handled? Would the proposed registry rule make terminal loss fail safely—for example, a lost final exit leaves a process registered—under the supported ordering and visibility semantics? Or is there a counterexample in which the registry can become empty while an unobserved descendant survives? 5. Synchronization, observer failure and delegated work Does es_sync_client provide any loss/completeness information beyond draining preceding queued messages? Its documented callbacks also run for a destroyed or null client, so we would not interpret callback arrival alone as successful completion. Is there a supported mechanism to distinguish a healthy drain from invalidation? What does “instigates” cover for this client? In particular, can it observe or attribute work executed by existing launchd/XPC services, or by unrelated processes receiving file descriptors? We would treat such work as outside a lineage-only closure claim unless it is explicitly covered or independently excluded. Does this client provide any supported protection against a same-UID workload stopping, killing or otherwise interfering with its observer, or must that isolation be supplied separately? Observer failure would invalidate the run; we are not assuming ES supplies a write barrier for evidence files. 6. Supported cleanup and deployment Is there a supported public mechanism to signal a non-child descendant by process-lifetime identity, without a PID-reuse race between observing it and sending a signal? Is there a recommended approach if the observer cannot wait on that process? We do not want to depend on private libproc functions as an application contract. Finally, is this use case eligible for com.apple.developer.endpoint-security.client in a standalone signed command-line observer, and what supported signing/provisioning or packaging requirements apply? This is a request for guidance, not an entitlement application. Our central question is whether supported APIs can establish complete descendant-process closure under these constraints. If they cannot, we would appreciate a clear statement of that limitation or a supported alternative. Thank you. Documentation consulted: es_new_descendants_client es_sync_client global_seq_num es_process_t
Replies
6
Boosts
0
Views
909
Activity
Oct ’26
Could not set environment: 150: Operation not permitted while System Integrity Protection is engaged
Hi. After the recent update of Ventura to 13.4 and Big Sur to 11.7.7 all of a sudden "launchctl setenv" returns the following errors. Could not set environment: 150: Operation not permitted while System Integrity Protection is engaged Is there any workaround to fix this?
Replies
7
Boosts
0
Views
5.4k
Activity
Oct ’26
XPCSession.cancel does not immediately cancel
I'm using an XPCSession to send a message to a service/agent. When calling session.cancel(reason: "stop") the connection is not immediately canceled. The session seems to wait for any pending replies from the service. According to the docs for XPCSession.cancel: When you cancel a session, it discards any unsent messages and invalidates its connection. If there are messages awaiting replies, the session calls the reply handlers with an appropriate XPCRichError. This does seem to imply that messages waiting for replies are immediately canceled, however that's not the case. The service may be busy and may take a while to respond, or it may not reply at all. The session is only canceled after all enqueued messages get a reply from the service. let session = try XPCSession(xpcService: "com.example.listener", cancellationHandler: { print("client session canceled") }) try session.send("Test", replyHandler: { reply in print("reply", reply) }) print("cancel") session.cancel(reason: "cancel") // calls cancellationHandler *after* receiving reply Is that expected behaviour? If the service does not respond at all the XPCService will never be canceled. Compared to xpc_connection_create + xpc_connection_cancel(connection) this does seem to immediately cancel the connection and call the reply_handler and event_handler. This does not wait for pending replies from the service. Is there an alternative way to force cancel an XPCSession? Main goal is to protect against two potential issues: The service is busy and doesn't respond in time. The client fires a timeout and wants to disconnect/reconnect, but the cancellationHandler is not called until service responds. So the timeout is not useful, client needs to wait for a reply anyway. The service does not respond at all. This could for example happen if a Launch Agent is improperly configured. The mach service is registered, but the agent may not launch. Sending a message on the XPCSession will never receive a reply.
Replies
3
Boosts
0
Views
235
Activity
Oct ’26
Sandboxed helper keeps running after the app is turned off in Background App Activity
Short version: we run a sandboxed helper as a hidden service account, started at boot by an SMAppService daemon. It works, even before login. But when the user turns our app off in Background App Activity, only the daemon stops. The helper keeps running. Is this setup supported, and what's the right way to manage the helper? What we want A Developer ID signed, notarized app (not Mac App Store) with a helper that parses untrusted input. The helper should: run as a dedicated, hidden, non-login local account; use App Sandbox, with its own container; be available before anyone logs in (after FileVault unlock). What we built An unsandboxed root LaunchDaemon, registered with SMAppService.daemon, runs this at boot: launchctl bootstrap user/<serviceUID> <fixed-agent-plist> The agent plist uses LimitLoadToSessionType=Background. The helper is a nested app in the same bundle, with com.apple.security.app-sandbox=true. We don't create a GUI session, change UID after the sandbox starts, or use private APIs. What we measured macOS 27.0 (26A428), arm64, dummy data only: Register and approve: the daemon starts. The helper starts as UID 60000, its container works, and reads outside it are denied. Turn the app off in Background App Activity: the daemon gets SIGTERM and stops. The helper keeps running (same PID). Turn it back on: the daemon starts again. Its bootstrap returns exit 5, because the old helper is still loaded. Call unregister(): the daemon stops. The helper keeps running. Cold boot (tested with a plain /Library/LaunchDaemons job, not yet SMAppService): the helper started and worked before login finished. For comparison, running the same sandboxed helper as a system daemon with UserName set to this account fails before main: Incoming message euid:60000 does not match secinitd uid:0. Questions Is this setup supported for shipping, including the sandbox starting before anyone logs in? Does the approval for daemon-bundled helpers cover a helper bootstrapped into another account's domain? Our plan: when the daemon gets SIGTERM, it runs bootout on the helper and its domain, and it treats bootstrap exit 5 as "already loaded". Is that the intended pattern, or is there a supported way for the helper to follow the app's Background App Activity setting? If this setup isn't supported, what public mechanism gives a sandboxed helper its own non-root identity before login? I can share the plists, entitlements and logs from a minimal reproducer.
Replies
6
Boosts
0
Views
679
Activity
Oct ’26
AlarmKit custom LiveActivityIntent: can executions overlap or be redelivered across app relaunch?
Hello, I'm developing an iPhone alarm app with AlarmKit. The alert has a custom secondary button whose intent conforms to LiveActivityIntent, declares supportedModes: .background and authenticationPolicy: .alwaysAllowed, and passes an alarm ID to app code from a @MainActor perform() implementation. The intent lives in the app target. It is not shared with a widget or an App Intents extension. The operation persists an in-progress record, awaits scheduling a new alarm, cancels the original only after scheduling succeeds, and then persists completion. After an interruption or relaunch, recovery reads the persisted original and candidate IDs and checks the system's alarm inventory. I want to understand which execution guarantees the app can rely on, so that recovery never schedules a duplicate alarm or cancels a valid candidate. I've read the LiveActivityIntent and App Intents runtime documentation. I understand how execution placement and foreground/background modes are described, but I couldn't find a public guarantee about overlap or redelivery when the app process is replaced. To be clear, I have not observed two simultaneous processes or duplicate execution in this setup. This is a question about what the app may assume, not a bug report. Questions For this app-target LiveActivityIntent configuration on iOS/iPadOS 26.x, can an older process of the same app still be executing an alarm-button intent while a newly launched process begins another invocation? Is there a documented single-process or handover guarantee an app may rely on? I'd appreciate it if the answer could distinguish multiple concurrent invocations within one process from overlap between an old and a newly launched process. Can the same alarm-button action be redelivered after an interruption or relaunch, including after perform() has thrown or returned? Which serialization or at-most-once guarantees, if any, apply to invocations for the same alarm ID, and which duplicate-delivery defenses must the app provide? I'm not assuming that every invocation comes from a new user tap. If the process that issued an AlarmKit scheduling or cancellation request terminates, may the app assume that the request has either completed or been abandoned before a newly launched process calls AlarmKit? If not, which public API checks or sequencing are recommended before recovery modifies the original or candidate alarm? I'm looking for supported app-level assumptions and recommended safeguards, not internal process lifecycle details. The app must preserve valid alarms and must never report an uncertain result as success. The shipping target is iPhone, with a minimum deployment target of 26.1. Earlier isolated testing on an iPad (9th generation, including iPadOS 26.7) did not show the overlap described above. Related question about the alert presentation after an intent error: [https://developer.apple.com/forums/thread/849075] Thank you!
Replies
0
Boosts
0
Views
348
Activity
Oct ’26
Supported macOS design for safely terminating an app-owned helper subtree?
I am designing a bounded local diagnostic helper for macOS. It would run only purpose-built helpers supplied by the application, not third-party or untrusted code. The design question is how to stop exactly those helpers and their descendants on timeout, without affecting an unrelated process or incorrectly reporting that cleanup is complete. This is a public-API suitability question, not a report of a reproduced macOS bug. The intended diagnostic is not an antivirus or endpoint-detection product. The required properties are: Identify each owned process by its lifetime and association with this helper run, not a numeric PID or process-group ID alone. Account for descendants across fork/exec, parent exit or reparenting, and process-group/session changes. Observing that a descendant escaped is not equivalent to preventing an escape. Terminate only the still-owned processes without a stale-identity race between checking ownership and signaling. Report completion only when all owned descendants have stopped and no new owned descendants can appear. Leader exit, IPC disconnection, or an unauthenticated empty process list would not be sufficient. Lost events or uncertain membership must leave the outcome inconclusive. Which supported public API or service/containment architecture can provide these properties? If they cannot all be guaranteed, which constraint should be changed and what guarantee can the supported alternative actually provide? I have reviewed the documentation for es_new_descendants_client and es_sync_client. The remaining questions are: Is a descendant-scoped Endpoint Security client appropriate for this non-security-product diagnostic? If so, which documented entitlement and packaging route applies? I am asking about eligibility, not assuming it. Does any supported design combine lifetime-safe control with containment of the whole owned subtree, including concurrent descendant creation? Merely receiving events would not establish that property. What additional protocol, if any, makes a synchronization callback sufficient to establish complete termination when client destruction, event loss, and concurrent activity are possible? I am not treating that callback alone as proof that no owned process remains. I can redesign around a helper that cannot create descendants if that is the supported approach. In that case, what supported mechanism enforces that restriction and what termination guarantees remain? So far, a standalone C harness has passed eleven fabricated-input cases with assertions enabled. It exercised no Endpoint Security client, process-tree creation/enumeration/control, or application behavior. It is not a runtime reproducer for this API-design question and does not establish native lifecycle safety. Pointers to documented guarantees, limitations, or an Apple sample would help me choose the architecture before preparing a narrowly scoped native test. I am not seeking private APIs or a way to disable platform protections. No logs, source archive, or binary is attached.
Replies
1
Boosts
0
Views
543
Activity
Sep ’26
Supported macOS confinement for a supervised process tree
I am evaluating a local diagnostic design before implementation or deployment and need to identify a public, supported macOS confinement mechanism. Proposed arrangement: A privileged custodian remains outside a separate privileged guardian's process group. The guardian launches a fixed diagnostic parent under a dedicated unprivileged identity. That parent sequentially launches three fixed sandboxed Python workloads, one child at a time. The current termination design targets the guardian's process group. It must not rely on whole-host process scans or indiscriminate killing. The proposed sandbox profiles are allow-default with file/network restrictions; the test-child profiles deny process-fork. We have not established that these restrictions prevent an existing process from changing its own group or session. Is there a public, supported interface or configuration that keeps all workload descendants within the supervisor's termination boundary from the initial child transition through final cleanup, while still allowing the parent to launch its authorized sequential children? In particular, please clarify: Escape through setsid/setpgid, spawn attributes, exec or native-library paths. When enforcement begins and whether descendants can relax it. Behavior when the diagnostic parent or guardian exits. Required privileges, entitlements, and supported OS/SDK versions. If the described sandbox categories do not establish that property, please identify the supported alternative boundary, if one exists. A different boundary would require an explicit design change on our side. I am requesting documented interface behavior and limitations—not private sandbox internals, a review of project code, or an absolute termination guarantee during kernel failure. No experiment has been performed to establish this property.
Replies
0
Boosts
0
Views
255
Activity
Sep ’26
Supported lifecycle and termination guarantees for an embedded macOS XPC service
We are evaluating a lifecycle architecture for a local macOS application and would appreciate guidance on supported public APIs. Proposed architecture: A normally signed, non-root host application. One embedded XPC service with exactly one intended client. No application-created subprocesses inside the service. No privileged helper, persistent LaunchAgent, exported endpoints, private APIs, or reduced system security. One bounded operation per session. Failed or interrupted operations must not automatically be retried. Initial validation would use synthetic workloads only. Our current evaluation target is macOS 15.6 on Apple silicon, using the macOS 15.5 SDK. Please identify any relevant deployment-version limitations. The XPC overview (https://developer.apple.com/documentation/xpc) describes an embedded service as tied to its client's lifetime. We also understand that xpc_connection_cancel (https://developer.apple.com/documentation/xpc/xpc_connection_cancel(_:)) is asynchronous and non-preemptive; we are not treating connection cancellation as proof of service termination. We need clarification on these points: Client death and service startup Does the documented client-lifetime relationship cover client termination, including SIGKILL, during service startup before the first reply? Does it also cover an already running service that is blocked or stopped with SIGSTOP? Which behavior is guaranteed, and which timing or failure cases are intentionally unspecified? Timeout while the client remains alive What supported public mechanism should a normal application use to terminate its own unresponsive embedded service when an operation exceeds its deadline? We want to avoid PID enumeration, PID-reuse races, broad process-group signaling, and exporting a full task-control port. Is there a supported identity-bound termination mechanism? If not, what architecture does Apple recommend? A stopped or hung client remains alive, so we do not assume client-lifetime coupling handles that separate failure case. Observing termination Which public notification reliably identifies the exit of the particular service instance, as distinct from connection invalidation or a missing reply? Because launchd is the parent, the application cannot simply waitpid the service. Is reaping entirely launchd's responsibility, and what completion claim can the application legitimately make? Identity and required privileges Which public signing requirements, launch constraints, sandbox settings, or entitlements are necessary for this architecture? Please distinguish authentication before accepting work from constraints enforced before service code executes. We do not assume peer authentication also grants termination rights. Restart behavior After interruption, cancellation, client exit, or service failure, under what circumstances can launchd or subsequent XPC activity start a replacement service? What supported pattern prevents accidental resubmission or resumption of the same failed operation? We are not asking for hard real-time guarantees during kernel failure, or claiming that forced termination proves callback completion or explicit memory zeroization. If this combination of requirements is unsupported, identifying that boundary and the smallest supported architectural alternative would be a useful answer. Documentation references or a minimal public sample would be welcome.
Replies
3
Boosts
0
Views
346
Activity
Sep ’26
macOS 27 - my faceless bg-only app now appears in the Dock - how to get rid of that?
My macOS app Find Any File contains another app inside its Resources folder. It's a background-only app that checks if the user presses a hotkey, in which case it launches my app. Since macOS 27, when the hotkey app is running, it appears in the Dock with a "Running in Background" subtitle. That's totally not wanted. How do I make it not appear in the Dock? I've got both "LSBackgroundOnly" and "LSUIElement" set to true in the Info.plist, to no avail.
Replies
3
Boosts
0
Views
357
Activity
Sep ’26
[27.0beta] Wrong app shown as running in Background in Dock
I develop a tool on macOS which is composed of an UI app to manage the main app settings, and an Agent that runs in background doing some tasks ? (Running the agent is optional, can be launched from the UI app, and can be launched by macOS at startup with SMAppService. ) Agent has the LSUIElement flag set, and only shows a Menu Extra (or whatever it now named), and sometimes some notifications. The whole App package is bundled this way MainAppUI.app/Contents/Library/LoginItems/AppAgent.app (for SMAppService to work) This has been working correctly for years Now on macOS 27 beta, once I quit the UI App, having launched the Agent, the Dock reports the UI App is still running in background (with the grey dot) . But only the Agent is running, not the UI app process. Moreover, System Settings->Background apps reports both the UI app AND the Agent as both requesting to run in background. I would have expected only the Agent being listed in System Settings, and nothing appearing in the Dock. Is this a bug in the OS beta , showing the top-level container bundle as the app running in background instead of the executable direct container ? Or maybe it's on me and I should bundle my app differently ? (I cannot "reverse" the bundle and put the Agent as the main app, with UI "inside", as double clicking the main app should launch the UI App , not the Agent. ) BTW, filed FB23203848 for the same subject. thanks for any direction
Replies
3
Boosts
1
Views
1.2k
Activity
Sep ’26
Crashe__CFRunLoopServiceMachPort.cold 96% Foreground
Hello, we have encountered a large number of __CFRunLoopServiceMachPort.cold crashes on iOS 26. These crashes frequently occur when the app transitions from the background to the foreground or is launched after sitting idle for a period of time. Despite extensive analysis, we have been unable to find a solution. Currently, the crash data indicates that this issue is specific to iOS 26. We would greatly appreciate your assistance. Thank you very much! Hardware Model: iPhone18,1 OS Version: iPhone OS 26.5.2 (23F84) Release Type: User Baseband Version: 1.60.02 Crash Reporter Key: fda96a4036dcb83e124660e11b654c9484b81dae Incident Identifier: EF18C4DD-7624-42D0-BA72-F17BBC263B16 Time Awake Since Boot: 2900000 seconds Triggered by Thread: 0, Dispatch Queue: com.apple.main-thread Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x00000001917d316c Termination Reason: Namespace SIGNAL, Code 5, Trace/BPT trap: 5 Terminating Process: exc handler [82210] Application Specific Information: (ipc/rcv) invalid name Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 CoreFoundation 0x1917d316c __CFRunLoopServiceMachPort.cold.1 + 64 1 CoreFoundation 0x19168a444 __CFRunLoopServiceMachPort + 416 2 CoreFoundation 0x191654310 __CFRunLoopRun + 1188 3 CoreFoundation 0x19165354c _CFRunLoopRunSpecificWithOptions + 532 4 GraphicsServices 0x236df7498 GSEventRunModal + 120 5 UIKitCore 0x19734c244 -[UIApplication _run] + 796 6 UIKitCore 0x1972b7158 UIApplicationMain + 332 7 KMMVideo 0x1047fe24c 0x104304000 + 5218892 8 dyld 0x18e261c1c start + 6928 Thread 1 name: transmit_hls_7683_193735 Thread 1: 0 libsystem_kernel.dylib 0x2407da5e8 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x1f0852b48 _pthread_cond_wait + 980 2 libc++.1.dylib 0x1a0d5dbcc std::__1::condition_variable::wait(std::__1::unique_lockstd::__1::mutex&) + 32 3 iOSPlayer 0x118cd6114 a_task_runner::worker() + 116 4 iOSPlayer 0x118cd5650 a_task_runner::work_thread() + 196 5 iOSPlayer 0x118cd654c void* std::__1::__thread_proxy[abi:ne200100]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_deletestd::__1::__thread_struct>, void (a_task_runner::)(), a_task_runner>>(void*) + 72 6 libsystem_pthread.dylib 0x1f0854438 _pthread_start + 136 7 libsystem_pthread.dylib 0x1f08508cc thread_start + 8 Thread 2: 0 libsystem_kernel.dylib 0x2407d9ed8 read + 8 1 XLTranscodeKit 0x115bb5f4c runtime.read_trampoline.abi0 + 28 Thread 3: Thread 4: 0 libsystem_kernel.dylib 0x2407da5e8 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x1f0852b48 _pthread_cond_wait + 980 2 XLTranscodeKit 0x115bb6648 runtime.pthread_cond_wait_trampoline.abi0 + 24 3 XLTranscodeKit 0x115bb4fb8 runtime.asmcgocall.abi0 + 200 4 ??? 0xd65f03c0 ??? Thread 5: 0 XLTranscodeKit 0x115b3eb68 */bytealg.IndexByteString + 40 1 XLTranscodeKit 0x115b966b8 runtime.findnull + 104 Thread 6: 0 libsystem_kernel.dylib 0x2407db8dc kevent + 8 1 XLTranscodeKit 0x115bb6398 runtime.kevent_trampoline.abi0 + 40 Thread 7: 0 libsystem_kernel.dylib 0x2407da5e8 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x1f0852b48 _pthread_cond_wait + 980 2 XLTranscodeKit 0x115bb6648 runtime.pthread_cond_wait_trampoline.abi0 + 24 3 XLTranscodeKit 0x115bb4fb8 runtime.asmcgocall.abi0 + 200 4 ??? 0xd65f03c0 ???
Replies
3
Boosts
0
Views
501
Activity
Sep ’26
Can an ExtensionFoundation-based extension on macOS have its own extension point and host its own extensions?
It is possible for an extension to an app (based on ExtensionFoundation) to declare its own extension point and host its own ExtensionFoundation extensions? Based on the documentation, I am guessing the answer is no, but worth double-checking. What would be the reason to prevent this? Every ExtensionFoundation extension runs in its own process, and may have need to be extended safely just as its host app does. Thank you!
Replies
3
Boosts
0
Views
416
Activity
Sep ’26
Is suspended spawn + audit_token_t matching a supported security boundary for one exact macOS process occurrence?
I’m designing a macOS privileged-service boundary and I’d like to clarify whether a process-occurrence authentication pattern previously described by Apple DTS is a supported shipping security contract, rather than just behaviour that happens to work on current macOS. Target: current macOS 26.x, using public APIs only. Threat model An arbitrary hostile process may run as the same ordinary, non-admin login user as the application. The attacker can launch an exact second copy of the legitimately signed requester binary. The attacker cannot obtain administrator / Touch ID authorization and does not control root, SIP, Recovery, the kernel, or the code-signing infrastructure. Desired property After a fresh Human-authorized operation, a root LaunchDaemon should grant authority to one specific requester process occurrence, not to every process having the same code-signing identity. Apple DTS thread 842442 describes a pattern based on: launching the requester suspended with posix_spawn(..., POSIX_SPAWN_START_SUSPENDED); obtaining a name/task port for that process; reading its TASK_AUDIT_TOKEN; resuming the process; and accepting only Mach messages whose kernel audit trailer identifies that same process occurrence. Thread 842442 also describes this area as being on “thin compatibility ice”, which is why I do not want to build a security boundary on behaviour that Apple does not intend applications to rely on. My core question is: Can a shipping macOS application rely on a pre-bound audit_token_t obtained from a suspended child and compare it against the audit token in subsequent raw Mach message trailers as a supported security boundary for that exact process occurrence? In particular, I need to know whether the supported contract covers: distinguishing another process with the exact same signed executable; PID reuse after the original process exits; messages queued before or around sender termination; a Mach send right transferred to another process — does the receiver see the audit token of the process that actually sends each message?; later exec by the original process; and whether full audit_token_t equality is an appropriate supported comparison for this purpose. If that is not a supported shipping contract, is there a current public XPC API that provides the equivalent property: binding one privileged-service session to one exact process occurrence rather than merely to its code-signing identity? I’m specifically trying to distinguish: code identity = this is an approved executable from mission authority = this one particular authorized process occurrence I’m happy with a negative answer if macOS does not expose a stable public contract for the latter. Related Apple DTS discussion: https://developer.apple.com/forums/thread/842442
Replies
11
Boosts
0
Views
895
Activity
Sep ’26
Supported OS-owned lifetime for one-shot macOS work after its controller exits
I’m designing a macOS utility that needs to run a bounded, one-shot diagnostic and collect its result. The lifetime problem is: A controller asks for the diagnostic to start. The diagnostic may begin successfully. The controller can then fail immediately — potentially before it has retained the child’s PID or established output collection. The diagnostic may close stdin/stdout/stderr while continuing to run. The diagnostic must not become an unmanaged orphan if the controller disappears. A focused test case uses Foundation.Process: Controller launches Child. Controller immediately exits with _exit(42), without waiting for Child or retaining its process identifier. Child calls setsid(), closes stdin/stdout/stderr, stays alive for up to 120 seconds, then exits. What I’m trying to establish is the supported macOS lifecycle boundary, rather than inventing a cleanup scheme around PIDs. Is there a supported per-user launchd or other OS-managed mechanism where the OS assumes responsibility for the job before the diagnostic process can start, such that the requesting controller may subsequently fail without leaving an unmanaged process? Specifically: At what point does the OS own the lifetime relative to registration and process creation? What supported mechanism bounds or terminates the job if the requesting controller disappears? Is there a supported hard execution-time limit, rather than an idle-time concept? How are descendants or process groups contained, and does calling setsid() conflict with that containment? What completion or failure information remains available to a later controller after the original requester has died? Are there important per-user, privilege, sandboxing, signing, or macOS-version limitations? I’m not reporting an Apple bug and I’m not asking for a custom recovery implementation. I’m trying to identify the documented supported lifetime mechanism and its guarantees and limitations before choosing an architecture. Environment: macOS 26.6.2 Apple silicon Foundation.Process is used by the focused reproducer Apple Developer Technical Support suggested I start a new thread for this specific question in Processes & Concurrency.
Replies
4
Boosts
0
Views
405
Activity
Sep ’26