What does RunningBoard do? 2 Managed apps
In the previous article I looked at how RunningBoard monitored an ordinary notarized macOS app, but didn’t manage its life cycle by limiting its access to resources such as memory, CPU or GPU. Here I extend that to the two types of app that are most likely to be managed by RunningBoard, Catalyst and iPadOS apps.
Catalyst
Apple introduced this as a streamlined way for developers of iPadOS apps to be able to create a version that runs in macOS from Catalina onwards. When running on macOS, Catalyst apps are dependent on RunningBoard’s life cycle management, UIKitSystem (which first appeared in macOS Mojave) to bridge between UIKit’s class framework in iPadOS and those in macOS, and additional -board services including FrontBoard, FuseBoard and BaseBoard. Catalyst apps also have access to some features in AppKit, the central class framework for apps developed for macOS, at least until SwiftUI has started to replace it.
Although Apple might have had high hopes of Catalyst bringing many new apps from iPadOS, it hasn’t proved popular with third-party developers, and the ability of Apple silicon Macs to run iPadOS and iOS apps has reduced its relevance to users.
Job descriptions
RunningBoard’s lengthy job descriptions recorded in the log early during the app launch process allow regular macOS, Catalyst and iPadOS apps to be distinguished easily. At the start of each job description, the Platform is recorded, 1 for macOS, 2 for iPadOS, and 6 for Catalyst.
Other differences in job descriptions include:
- In EnvironmentVariables, iPadOS adds Container values for CFFIXED_USER_HOME and _DYLD_CLOSURE_HOME.
- In AdditionalProperties, both Catalyst and iPadOS apps have “Managed” set to true, and SpawnConstraints containing their CDHashes.
- In AdditionalProperties, iPadOS apps have a BeforeTranslocationBundlePath specified.
Catalyst launch
Catalyst apps are launched using the same basic sequence of events as regular macOS apps, with some additional overhead resulting from their UIKitSystem and -board service support. However, when they reach RunningBoard they become managed, in the test case denying it access to the GPU:00.984295 com.apple.runningboard [app…] Memory Limits: active 0 inactive 0
00.984303 com.apple.runningboard [app…] This process will be managed.
00.984307 com.apple.runningboard <private> is not freezer eligible, disabling freezing.
00.985634 com.apple.runningboard [app…] Set jetsam priority to 0 [0] flag[1]
00.985649 com.apple.runningboard 3638 Set Darwin GPU to "deny"
00.985708 com.apple.runningboard 3638 setGPURole role to 2 (no effect for this process)
00.985715 com.apple.runningboard [app…] Disabled CPU monitoring
00.985716 com.apple.runningboard [app…] Reset CPU monitoring limits to defaults
00.985717 com.apple.runningboard [app…] Resumed CPU monitoring
where [app…] is the app identifier.
Later management includes regular state updates, such as01.209325 com.apple.runningboard Update delivered for [app…] with taskState 4
01.209327 com.apple.runningboard Received state update for 3638 (app…, running-active-Visible
iPadOS launch
iPadOS and iOS apps are launched completely differently on macOS. Initially MIS, presumably MobileInstallationService, validates the app and its Wrapper, which are translocated to a hidden location in /private/var/folders, from where the wrapped app will be launched. Translocation isn’t intended as a security measure, as it is with macOS apps run there when in quarantine, but is required to work around two limitations:
- iOS/iPadOS apps may expect to be run from a path that doesn’t contain whitespaces. The path to the translocation folder guarantees that.
- In macOS, the user can run apps from (almost) any path, such as the Desktop, and can rename apps. The translocation path ensures the app’s name and path remain fixed.
Those are reflected in the following log entries, which have changed little since Big Sur:00.946662 com.apple.mis Bundle: <private>
00.946662 com.apple.mis Is main executable: 0
00.953668 com.apple.syspolicy MIS validation result: 0
00.953673 com.apple.syspolicy Valid app wrapper: <private>
00.953719 com.apple.syspolicy appWrapperPolicyResult: <private>, AWPolicyResult: 1,1,0
00.956399 com.apple.securityd SecTranslocateCreateGeneric: created /private/var/folders/x4/[…]/d/Wrapper
00.965043 com.apple.launchservices LAUNCH: translocate to <private> from <private>
01.047816 com.apple.launchservices Marking <private> as .requiresSecureLaunch because it is PLATFORM_IOS or PLATFORM_MACCATALYST.
01.049878 com.apple.launchservices LAUNCH: _LSLaunchThruRunningboard: com.parrot.freeflight6 / <private>
FairPlay DRM is then accessed through the Secure Enclave Processor.
When it reaches the attention of RunningBoard, the app’s memory limits are set, it’s denied the GPU, and it’s then managed through its life cycle.02.365127 com.apple.runningboard [app…:3466] Memory Limits: active 16384 inactive 16384
02.365137 com.apple.runningboard [app…:3466] This process will be managed.
02.365142 com.apple.runningboard <private> is not freezer eligible, disabling freezing.
02.365150 com.apple.runningboard Now tracking process: [app…:3466]
02.367347 com.apple.runningboard 3466 Set Darwin GPU to "deny"
02.367450 com.apple.runningboard 3466 setGPURole role to 2 (no effect for this process)
02.367460 com.apple.runningboard [app…:3466] Disabled CPU monitoring
02.367462 com.apple.runningboard [app…:3466] Reset CPU monitoring limits to defaults
02.367464 com.apple.runningboard [app…:3466] Resumed CPU monitoring
02.367496 com.apple.runningboard [app…:3466] set Memory Limits to Hard Inactive (16384)
where [app…:3466] is the app identifier.
That’s followed by frequent assertions and state updates.
PerfPowerServices
Some users have reported RunningBoard using high CPU %, sometimes associated with high levels from PerfPowerServices. By chance, during these tests I encountered a similar situation. For several seconds, the log was filled with entries recording com.apple.PerfPowerServices
requesting management information from RunningBoard about most if not all services running at that time.
Many entry sequences followed the pattern:00.004740 com.apple.runningboard PERF: Received request from [osservice<com.apple.PerfPowerServices>:976] (euid 0, auid 0) (persona (null)): lookupHandleForPredicate:error:
00.004743 com.apple.runningboard PERF: Received lookupHandleForPredicate request from [osservice<com.apple.PerfPowerServices>:976] (euid 0, auid 0) (persona (null))
00.004971 com.apple.runningboard _multiInstance = 0
00.004973 com.apple.runningboard _executablePath = /usr/sbin/cfprefsd
00.004974 com.apple.runningboard no additional launch properties found for <private>
00.005020 com.apple.runningboard _resolveProcessWithIdentifier pid 2712 euid 277 auid 277
00.005040 com.apple.runningboard Resolved pid 2712 to [osservice<com.apple.cfprefsd.xpc.agent(277)>:2712]
00.005089 com.apple.runningboard memorystatus_control error: MEMORYSTATUS_CMD_CONVERT_MEMLIMIT_MB(-1) returned -1 22 (Invalid argument)
00.005091 com.apple.runningboard memorystatus_control error: MEMORYSTATUS_CMD_CONVERT_MEMLIMIT_MB(0) returned -1 22 (Invalid argument)
00.007828 com.apple.runningboard Full encoding handle <private>, with data 44b0344500000a98, and pid 2712
00.008019 com.apple.runningboard [osservice<com.apple.cfprefsd.xpc.agent(277)>:2712] is not RunningBoard jetsam managed.
00.008040 com.apple.runningboard [osservice<com.apple.cfprefsd.xpc.agent(277)>:2712] This process will not be managed.
for multiple copies of cfprefsd
, and many other processes.
Presumably PerfPowerServices is concerned with performance power services, but the purpose of these many requests is unknown. After a few seconds of frenetic activity, and more than 10,000 log entries, this subsided and normal running was resumed. If anyone can provide an explanation, I’d be most grateful.
Key points
- RunningBoard job descriptions record the app Platform: 1 for macOS, 2 for iPadOS, and 6 for Catalyst.
- Catalyst apps are managed by RunningBoard through a relatively normal launch sequence.
- iPadOS/iOS apps are launched differently, in a Wrapper and translocated to avoid problems with their name and path in macOS.
- iPadOS/iOS apps rely on FairPlay DRM accessed through the Secure Enclave.
- iPadOS/iOS apps have memory limits imposed by RunningBoard.
- PerfPowerServices can busy RunningBoard with many requests and high CPU %. The cause is unknown, but that high activity should settle of its own accord.