iOS 如何调试由于超过 60 秒 80% cpu 限制而导致应用程序终止

The*_*per 5 ios swiftui

我的应用程序在后台运行时收集传感器数据(位置、步数、心率等)。

有没有办法从 cpu_resource_fatal 日志(An App.cpu_resource_fatal-2021-06-19-043941.ips.synced)确定我的代码中 cpu 达到最大的位置?

我有时间分析我的应用程序,但一切看起来都不错。我遇到的问题是,该应用程序会在 10 分钟到几个小时之间随机终止,因此没有真正的迹象表明导致此问题的原因。

是否有任何工具可以指示该代码在我的代码中的位置以及如何继续对其进行解码的说明?

  19  ??? (libdyld.dylib + 4416) [0x19ba7e140]
  19  ??? (An App + 36856) [0x102a38ff8]
Run Code Online (Sandbox Code Playgroud)

我一直在寻找答案,但没有找到任何帮助。

这是日志文件的部分输出:

{"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]
Run Code Online (Sandbox Code Playgroud)

The*_*per 1

虽然我试图从符号崩溃报告中了解我的应用程序在代码中的何处被终止,但这并不是最终为我解决问题的原因,主要是因为符号代码指向 SwiftUI 内部代码中的问题。

我忘记了关于在后台运行的最重要的规则,那就是在主线程上尽可能少地执行操作,即防止代码更新视图,或者实际上将不负责更新 @Published 变量的代码移出主线程。

我的代码在后台运行时 CPU 占用率约为 15%,在我完成代码更新后,我将其降至 3%,同时不断从核心运动、核心数据和蓝牙捕获数据。然后它非常高兴在后台运行几个小时,在一次测试中我让它连续运行了两天。

对我来说最大的帮助是 Xcode 调试导航器,我可以在其中监视 cpu 使用情况,因为这是唯一以百分比形式提供 cpu 使用情况的工具。我还发现我可以在模拟器中微调我的代码,然后在实际设备上进行确认,从而加快开发速度。

我的应用程序大量使用组合,并且存在一些我没有预料到的怪癖,例如更新 @Published var,然后将其用于更新视图上的心率。这导致了 cpu 使用率的激增,为了解决这个问题,我刚刚从 var 中删除了 @Published 并解决了这个问题。我不知道为什么其他 @Published 变量没有引起任何问题。

使用时间分析器可以显示主线程上正在运行的代码量,从而可以查明代码中 CPU 利用率高的位置。

使用路标可以测量特定代码块运行的时间。

Thread.isMainThread 返回一个布尔值以显示代码是否在主线程上运行,并允许对组合发布者代码和任何其他长时间运行的代码进行健全性检查。

希望这可以帮助处于类似情况的其他人。

这些是我使用的资源: