[iOS][Swift]スタックトレース(コールスタック)を表示する2つの方法
公開日:
:
最終更新日:2020/07/09
iOSアプリ開発 Foundation, Swift, Xcode
記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。
こんにちは、@akio0911です。
iOSアプリ開発で、スタックトレース(コールスタック)を表示する方法を2つ紹介したいと思います。
1. ブレークポイントを使う
コールスタックを確認したい箇所にブレークポイントを設定し、以下のように設定します。
- Action: Debugger Command
- コマンド: bt
- Automatically continue after evaluating actions: チェック入れる
実行時に設定箇所を通過すると、以下のような内容がConsole領域に出力されます。
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 * frame #0: 0x000000010fd4c16c CallStack`ViewController.viewDidLoad(self=0x00007fcb824063d0) -> () at ViewController.swift:14 frame #1: 0x000000010fd4c222 CallStack`@objc ViewController.viewDidLoad() -> () at ViewController.swift:0 frame #2: 0x000000011099a01a UIKit`-[UIViewController loadViewIfRequired] + 1235 frame #3: 0x000000011099a45a UIKit`-[UIViewController view] + 27 frame #4: 0x000000011086298a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65 frame #5: 0x0000000110863070 UIKit`-[UIWindow _setHidden:forced:] + 294 frame #6: 0x0000000110875ebe UIKit`-[UIWindow makeKeyAndVisible] + 42 frame #7: 0x00000001107ef37f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346 frame #8: 0x00000001107f55e4 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709 frame #9: 0x00000001107f27f3 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182 frame #10: 0x000000011478f5f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24 frame #11: 0x000000011478f46d FrontBoardServices`-[FBSSerialQueue _performNext] + 186 frame #12: 0x000000011478f7f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45 frame #13: 0x0000000113025c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 frame #14: 0x000000011300b0cf CoreFoundation`__CFRunLoopDoSources0 + 527 frame #15: 0x000000011300a5ff CoreFoundation`__CFRunLoopRun + 911 frame #16: 0x000000011300a016 CoreFoundation`CFRunLoopRunSpecific + 406 frame #17: 0x00000001107f108f UIKit`-[UIApplication _run] + 468 frame #18: 0x00000001107f7134 UIKit`UIApplicationMain + 159 frame #19: 0x000000010fd4d2d7 CallStack`main at AppDelegate.swift:12 frame #20: 0x000000011401f65d libdyld.dylib`start + 1 frame #21: 0x000000011401f65d libdyld.dylib`start + 1
2. Thread.callStackSymbolsを使う
Thread.callStackSymbolsを使うと、その時点での現在のスレッドのコールスタックシンボルの配列を取得することができます。
以下、使用例です。
for symbol in Thread.callStackSymbols { print(symbol) }
実際に使う時は、上記のコードをユーティリティメソッドなどにまとめてあげると良いでしょう。
上記のコードを実行した時の出力例を以下に示します。
0 CallStack 0x0000000105eb8874 _TFC9CallStack14ViewController11viewDidLoadfT_T_ + 164 1 CallStack 0x0000000105eb8ad2 _TToFC9CallStack14ViewController11viewDidLoadfT_T_ + 34 2 UIKit 0x0000000106b0501a -[UIViewController loadViewIfRequired] + 1235 3 UIKit 0x0000000106b0545a -[UIViewController view] + 27 4 UIKit 0x00000001069cd98a -[UIWindow addRootViewControllerViewIfPossible] + 65 5 UIKit 0x00000001069ce070 -[UIWindow _setHidden:forced:] + 294 6 UIKit 0x00000001069e0ebe -[UIWindow makeKeyAndVisible] + 42 7 UIKit 0x000000010695a37f -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346 8 UIKit 0x00000001069605e4 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1709 9 UIKit 0x000000010695d7f3 -[UIApplication workspaceDidEndTransaction:] + 182 10 FrontBoardServices 0x000000010a9ad5f6 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24 11 FrontBoardServices 0x000000010a9ad46d -[FBSSerialQueue _performNext] + 186 12 FrontBoardServices 0x000000010a9ad7f6 -[FBSSerialQueue _performNextFromRunLoopSource] + 45 13 CoreFoundation 0x0000000109190c01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 14 CoreFoundation 0x00000001091760cf __CFRunLoopDoSources0 + 527 15 CoreFoundation 0x00000001091755ff __CFRunLoopRun + 911 16 CoreFoundation 0x0000000109175016 CFRunLoopRunSpecific + 406 17 UIKit 0x000000010695c08f -[UIApplication _run] + 468 18 UIKit 0x0000000106962134 UIApplicationMain + 159 19 CallStack 0x0000000105eb9bb7 main + 55 20 libdyld.dylib 0x000000010a18a65d start + 1
ちなみにThread.callStackSymbolsを使うと、現在実行中のメソッドがどのメソッドから呼び出されたか?などを判定することができそうですが、そのようなコードを実際の実装に使うのはよくなさそうですね。
@akio0911はこう思った。
今回紹介したブレークポイントを使う方法はコードを編集しないので再ビルドせずに実行することが可能ですが、ブレークポイントに慣れていなければThread.callStackSymbolsがお手軽に使えるかなと思います。
シチュエーションや用途に合わせて、お好きな方を使ってみて下さい。
関連記事
この記事が気に入ったら「いいね!」しよう
Twitterで更新情報をゲット!