Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

What does RunningBoard do? 2 Managed apps

By: hoakley
15 July 2025 at 14:30

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 as
01.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.

LogUI build 60 reads iOS, iPadOS, macOS and other logarchives

By: hoakley
9 June 2025 at 14:30

Until now, LogUI has only been able to access the active log of your Mac, by reading it directly. There are occasions when you can’t do that, or want to preserve the log for future reference. You also can’t browse the log directly on any of Apple’s devices. In these cases, and others, the best solution is to make a logarchive, and browse that instead. I’m delighted to provide an update to LogUI that can browse logarchives, including those created in iOS, iPadOS, and on Apple’s other devices.

What is a logarchive?

A logarchive is an undocumented package containing copies of all the files from the active log at the moment the logarchive was created. They can be opened and browsed by Console, Consolation 3, Ulbow, the log command tool, and now by LogUI. Because they contain all the files that make up the log, they can be large, and typically range in size from about 300 MB to over 1 GB. All the files containing log entries are stored in their original binary tracev3 format, proprietary to Apple, and again undocumented, although that format has been reversed in the past.

Create a logarchive

The easiest way to create a logarchive is to run a sysdiagnose, and that’s the standard way for saving a logarchive on one of Apple’s devices. Methods vary by device, and include:

  • On a Mac, use the System Diagnostics… option in Activity Monitor’s Action tool, or press the Shift, Command, Control, Option and . keys at the same time, or run sudo sysdiagnose -f ~/Documents to save it to your Documents folder.
  • On an iPhone or iPad, press and hold both volume buttons and the side or top button at the same time, for about 2 seconds. This combination may trigger other features, though. The sysdiagnose file will be made available in Settings > Privacy & Security > Analytics & Improvements > Analytics Data, from where you can transfer it to your Mac.

Unpack the .tar.gz archive resulting from that, and you’ll find a system_logs.logarchive inside it.

On a Mac, you can instead use the log collect command to create a logarchive directly. For example,
log collect --output ~/Documents/my.logarchive --last 5m
collects the last 5 minutes of log in the specified logarchive package. macOS security will block you from trying to save that logarchive on an external volume, though.

My free log browser Ulbow uses another method for assembling logarchives, and the next build of LogUI will incorporate that and other tools for working with logarchives.

Browse a logarchive in LogUI

This new build of LogUI has a seventh tool, to Use Logarchive. Click on that and you’ll be prompted to select the logarchive to open and browse.

Because the dates and times used in the logarchive will be different from current clock time, the LogUI window displays red warning text just to the left of the Start time. Set the date and time to a period within the scope of that logarchive, and use the Get Log tool as normal.

The log excerpt shown in the screenshot above is taken from the kernel boot sequence of my iPhone 15 Pro, to demonstrate how this all works.

If you want to return that window to browsing the active log, click on the Use Logarchive tool again, but this time cancel the selection. Other windows will of course continue to browse the active log unless you set them to use a logarchive as well.

Coming soon

Although browsing saved log entries in a logarchive is exactly the same as those of the active log, dates and times can be a pain. If you want to check when log files in a logarchive were written, use the Finder’s contextual menu to show their contents, scroll to the foot of the folders inside, select the Persist folder and check the file creation dates there.

This is made even easier in the forthcoming new build of LogUI, which features a Logarchive Tool to help you navigate logarchives, and learn which date and time ranges are appropriate.

LogUI 1.0 build 60 is now available from here: logui160
and from its Product Page.

I’ll be along with a new build in a few days, once I have tested and documented its Logarchive Tool. In the meantime, I hope you’ll find LogUI useful for studying the first beta-releases of Apple’s new operating systems.

❌
❌