'iOS How to debug an app termination due to exceeding limit of 80% cpu over 60 seconds

My app is collecting sensor data (location, steps, heart rate, etc.) whilst running in the background.

Is there a way to determine where in my code the cpu was maxing out from the cpu_resource_fatal log (An App.cpu_resource_fatal-2021-06-19-043941.ips.synced)?

I have time profiled my app, but all looks ok. The issue I have is that the app is randomly terminated some where between 10's of minutes to several hours, so there is no real indication of what is causing this.

Are there any tools that would provide an indication of where in my code this is and instructions on how to proceed to decode it?

  19  ??? (libdyld.dylib + 4416) [0x19ba7e140]
  19  ??? (An App + 36856) [0x102a38ff8]

I have searched for an answer, but have found nothing to assist.

Here is the partial output from the log file:

{"app_name":"An App","timestamp":"2021-06-19 04:39:41.00 +0100","app_version":"1.0","slice_uuid":"6DBBF8FB-861D-388F-B086-B1338485456A","adam_id":0,"build_version":"1","bundleID":"com.msn.dev.An App","share_with_app_devs":1,"is_first_party":0,"bug_type":"206","os_version":"iPhone OS 14.6 (18F72)","incident_id":"18242B71-2C07-43FE-9C86-A9C8BBFD4A16","name":"An App"}
Date/Time:        2021-06-19 04:38:41.398 +0100
End time:         2021-06-19 04:39:41.190 +0100
OS Version:       iPhone OS 14.6 (Build 18F72)
Architecture:     arm64
Report Version:   32
Incident Identifier: 18242B71-2C07-43FE-9C86-A9C8BBFD4A16
Share With Devs:  Yes

Data Source:      Microstackshots
Shared Cache:     E0420A4C-044A-38AB-81C9-0681ED2C05D7 slid base address 0x19b9b8000, slide 0x1b9b8000

Command:          An App
Path:             /private/var/containers/Bundle/Application/4CFC1F43-62F5-43FD-9695-27B18E968E74/An App.app/An App
Identifier:       com.msn.dev.An App
Version:          1.0 (1)
Beta Identifier:  CA71DB36-08E5-48C4-9F3A-A15F652CF1F7
PID:              7087

Event:            cpu usage
Action taken:     Process killed
CPU:              48 seconds cpu time over 60 seconds (80% cpu average), exceeding limit of 80% cpu over 60 seconds
CPU limit:        48s
Limit duration:   60s
CPU used:         48s
CPU duration:     60s
Duration:         59.79s
Duration Sampled: 17.39s
Steps:            19

Hardware model:   iPhone10,6
Active cpus:      6


Heaviest stack for the target process:
  19  ??? (libdyld.dylib + 4416) [0x19ba7e140]
  19  ??? (An App + 36856) [0x102a38ff8]
  19  ??? (SwiftUI + 4401348) [0x1a231b8c4]
  19  ??? (SwiftUI + 8918208) [0x1a276a4c0]
  19  ??? (SwiftUI + 8918320) [0x1a276a530]
  19  ??? (UIKitCore + 11753060) [0x19e6d0664]
  19  ??? (UIKitCore + 11731176) [0x19e6cb0e8]
  19  ??? (GraphicsServices + 13680) [0x1b24a5570]
  19  ??? (CoreFoundation + 604184) [0x19bd9f818]
  19  ??? (CoreFoundation + 606548) [0x19bda0154]
  19  ??? (CoreFoundation + 605112) [0x19bd9fbb8]
  19  ??? (CoreFoundation + 628104) [0x19bda5588]
  19  ??? (SwiftUI + 2866992) [0x1a21a4f30]
  19  ??? (SwiftUI + 2866676) [0x1a21a4df4]
  19  ??? (libswiftObjectiveC.dylib + 8016) [0x1c0548f50]
  19  ??? (SwiftUI + 2847996) [0x1a21a04fc]
  19  ??? (SwiftUI + 2866704) [0x1a21a4e10]
  19  ??? (SwiftUI + 2866856) [0x1a21a4ea8]
  19  ??? (SwiftUI + 4575124) [0x1a2345f94]
  19  ??? (SwiftUI + 9362096) [0x1a27d6ab0]
  19  ??? (SwiftUI + 9356360) [0x1a27d5448]
  19  ??? (SwiftUI + 4418488) [0x1a231fbb8]
  19  ??? (SwiftUI + 8694596) [0x1a2733b44]
  19  ??? (SwiftUI + 8709728) [0x1a2737660]
  19  ??? (SwiftUI + 4432724) [0x1a2323354]
  19  ??? (SwiftUI + 9356392) [0x1a27d5468]
  19  ??? (SwiftUI + 9351292) [0x1a27d407c]
  19  ??? (SwiftUI + 9356560) [0x1a27d5510]
  19  ??? (SwiftUI + 9345968) [0x1a27d2bb0]
  19  ??? (AttributeGraph + 57416) [0x1c3355048]
  19  ??? (AttributeGraph + 21784) [0x1c334c518]
  19  ??? (AttributeGraph + 20744) [0x1c334c108]
  18  ??? (SwiftUI + 3340216) [0x1a22187b8]
  16  ??? (SwiftUI + 6473584) [0x1a2515770]
  16  ??? (SwiftUI + 3203020) [0x1a21f6fcc]
  16  ??? (SwiftUI + 6472548) [0x1a2515364]
  16  ??? (SwiftUI + 3229912) [0x1a21fd8d8]
  16  ??? (SwiftUI + 5650800) [0x1a244c970]
  16  ??? (SwiftUI + 9484856) [0x1a27f4a38]
  15  ??? (SwiftUI + 7413264) [0x1a25fae10]
  15  ??? (SwiftUI + 2957384) [0x1a21bb048]
  15  ??? (SwiftUI + 3618976) [0x1a225c8a0]
  15  ??? (SwiftUI + 6647036) [0x1a253fcfc]
  13  ??? (SwiftUI + 4110252) [0x1a22d47ac]
  12  ??? (libswiftCore.dylib + 2706436) [0x19fa1bc04]
  7   ??? (libswiftCore.dylib + 1016760) [0x19f87f3b8]
  5   ??? (libswiftCore.dylib + 3025652) [0x19fa69af4]
  4   ??? (libswiftCore.dylib + 3137112) [0x19fa84e58]
  3   ??? (libswiftCore.dylib + 3186576) [0x19fa90f90]


Solution 1:[1]

You are absolutely correct that you need to figure out what that process is. I have the same issue in an app that receives location updates in the background. But I have no idea what's causing it. In the end, I had to resort to symbolicating individual objects in each line using atos in the command line.

This document helped a lot:

https://developer.apple.com/documentation/xcode/adding-identifiable-symbol-names-to-a-crash-report

Pay close attention to the section titled Symbolicate the Crash Report with the Command Line, as you're going to want to find the dSYM file and link the addresses in the individual lines. It will look something like this:

atos -arch arm64 -o <PathToDSYMFile>/Contents/Resources/DWARF/An\ App -l <LoadAddress> 0x102a38ff8

Note that <LoadAddress> is probably listed at the bottom of the crash report in a section called "Binary Images." For me, it reads as such:

0x10257c000 - ??? <BundleID Redacted> 1.0 (1) <UUID Redacted>  /private/var/containers/Bundle/Application/<UUID Redacted>/LocationTester.app/LocationTester

Given all of this, there are two lines for me that were causing the issue, and they are both somewhat useless:

closure #1 in EventTableCell.body.getter (in LocationTester) (<compiler-generated>:0)
storeEnumTagSinglePayload for EventTableCell (in LocationTester) (<compiler-generated>:0)

The body getter seems to suggest that there is some sort of redraw going on in the SwiftUI view in the background in a view that is two or three navigation levels deeper than the view that was presented when the app went to the background, which I don't understand.

I really want to like SwiftUI, but until it matures, it's hard to choose it over UIKit.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 promacuser