Hi~
Hi~
文章目录
  1. 调用栈 (Call Stack) 和栈帧 (Stack Frame)
    1. 调用栈 (Call Stack)
    2. 栈帧 (Stack Frame)
  2. 示例
    1. 审查 SwiftUI 项目的 Call Stack 和 Stack Frame

代码调试基础:如何看懂调用栈和栈帧信息

调用栈 (Call Stack) 和栈帧 (Stack Frame)

调用栈 (Call Stack)

In computer science, a call stack is a stack data structure that stores information about the active subroutines of a computer program. This type of stack is also known as an execution stack, program stack, control stack, run-time stack, or machine stack, and is often shortened to simply “the stack”.

在计算机学中,调用栈(港台称「呼叫堆叠」)是指,一个存储计算机程序有关活跃子事务的栈数据结构。栈类型也同样被作为执行栈、程序栈、控制栈、运行时栈或者机器栈,并且经常简称为“栈”。

栈帧 (Stack Frame)

In computer science, a stack frame is a memory management strategy used to create and destroy temporary (automatic) variables in procedural programming languages. Among other things, use of a stack allows programming languages to allow recursive calling of subroutines. Stack frames only exist at run-time.

在计算机学中,一个栈帧是一个程序上用于创建和销毁临时(自动)变量的内存管理策略。在其他事务中,一个栈允许编程语言,以用于子事务的递归调用。栈帧仅在运行时退出。

示例

审查 SwiftUI 项目的 Call Stack 和 Stack Frame

用 Xcode 创建一个 SwiftUI 项目,在 contentView 函数后设置断点,程序运行后在 console 中输入 bt(backtrace) 查看详细的调用栈。通常在 Xcode 左边 「Show the Debug navigator」中的线程调用栈只是部分调用栈,会隐藏未开源码的相关栈帧。

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x000000010202aea0 SwiftUIDemo`closure #1 in SwiftUIDemoApp.body.getter at SwiftUIDemoApp.swift:15:18
frame #1: 0x00000001c494a65c SwiftUI`SwiftUI.WindowGroup.init(content: () -> τ_0_0) -> SwiftUI.WindowGroup<τ_0_0> + 96
frame #2: 0x000000010202ade0 SwiftUIDemo`SwiftUIDemoApp.body.getter(self=SwiftUIDemo.SwiftUIDemoApp @ scalar) at SwiftUIDemoApp.swift:13:9
frame #3: 0x000000010202b088 SwiftUIDemo`protocol witness for App.body.getter in conformance SwiftUIDemoApp at <compiler-generated>:0
frame #4: 0x00000001c5aa9b4c SwiftUI`___lldb_unnamed_symbol275986 + 1364
frame #5: 0x00000001c586bec4 SwiftUI`___lldb_unnamed_symbol256724 + 300
frame #6: 0x00000001c586bc38 SwiftUI`___lldb_unnamed_symbol256723 + 204
frame #7: 0x00000001c5374abc SwiftUI`___lldb_unnamed_symbol216776 + 28
frame #8: 0x00000001b2bdc75c AttributeGraph`AG::Graph::UpdateStack::update() + 504
frame #9: 0x00000001b2bdceec AttributeGraph`AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 432
frame #10: 0x00000001b2be4e90 AttributeGraph`AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 716
frame #11: 0x00000001b2bfbd24 AttributeGraph`AGGraphGetValue + 232
frame #12: 0x00000001c586bb1c SwiftUI`___lldb_unnamed_symbol256721 + 80
frame #13: 0x00000001c586be98 SwiftUI`___lldb_unnamed_symbol256724 + 256
frame #14: 0x00000001c586bc38 SwiftUI`___lldb_unnamed_symbol256723 + 204
frame #15: 0x00000001c5374abc SwiftUI`___lldb_unnamed_symbol216776 + 28
frame #16: 0x00000001b2bdc75c AttributeGraph`AG::Graph::UpdateStack::update() + 504
frame #17: 0x00000001b2bdceec AttributeGraph`AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 432
frame #18: 0x00000001b2be4e90 AttributeGraph`AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 716
frame #19: 0x00000001b2bfbd24 AttributeGraph`AGGraphGetValue + 232
frame #20: 0x00000001c494b3ec SwiftUI`___lldb_unnamed_symbol138618 + 64
frame #21: 0x00000001c494b4dc SwiftUI`___lldb_unnamed_symbol138620 + 152
frame #22: 0x00000001c5374abc SwiftUI`___lldb_unnamed_symbol216776 + 28
frame #23: 0x00000001b2bdc75c AttributeGraph`AG::Graph::UpdateStack::update() + 504
frame #24: 0x00000001b2bdceec AttributeGraph`AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 432
frame #25: 0x00000001b2be44ec AttributeGraph`AG::Graph::value_ref(AG::AttributeID, unsigned int, AGSwiftMetadata const*, unsigned char&) + 252
frame #26: 0x00000001b2bfbd70 AttributeGraph`AGGraphGetValue + 308
frame #27: 0x00000001c5aa8180 SwiftUI`___lldb_unnamed_symbol275929 + 60
frame #28: 0x00000001c49ae37c SwiftUI`___lldb_unnamed_symbol141796 + 176
frame #29: 0x00000001c49a9b50 SwiftUI`___lldb_unnamed_symbol141692 + 1144
frame #30: 0x00000001c49aaa88 SwiftUI`___lldb_unnamed_symbol141697 + 96
frame #31: 0x0000000184805e18 UIKitCore`+[UIScene _sceneForFBSScene:create:withSession:connectionOptions:] + 1012
frame #32: 0x00000001852f1644 UIKitCore`-[UIApplication _connectUISceneFromFBSScene:transitionContext:] + 804
frame #33: 0x00000001852f192c UIKitCore`-[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 356
frame #34: 0x0000000184de0cc4 UIKitCore`-[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 260
frame #35: 0x0000000186e03190 FrontBoardServices`-[FBSScene _callOutQueue_didCreateWithTransitionContext:completion:] + 296
frame #36: 0x0000000186e2c3d4 FrontBoardServices`__92-[FBSWorkspaceScenesClient createSceneWithIdentity:parameters:transitionContext:completion:]_block_invoke.82 + 224
frame #37: 0x0000000186e0fd6c FrontBoardServices`-[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 160
frame #38: 0x0000000186e2c14c FrontBoardServices`__92-[FBSWorkspaceScenesClient createSceneWithIdentity:parameters:transitionContext:completion:]_block_invoke + 284
frame #39: 0x000000010216593c libdispatch.dylib`_dispatch_client_callout + 16
frame #40: 0x0000000102169534 libdispatch.dylib`_dispatch_block_invoke_direct + 392
frame #41: 0x0000000186e4fb24 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 44
frame #42: 0x0000000186e4fa00 FrontBoardServices`-[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 196
frame #43: 0x0000000186e4fb58 FrontBoardServices`-[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 24
frame #44: 0x00000001803f1f18 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #45: 0x00000001803f1e60 CoreFoundation`__CFRunLoopDoSource0 + 172
frame #46: 0x00000001803f1628 CoreFoundation`__CFRunLoopDoSources0 + 320
frame #47: 0x00000001803ebcb8 CoreFoundation`__CFRunLoopRun + 768
frame #48: 0x00000001803eb5a4 CoreFoundation`CFRunLoopRunSpecific + 572
frame #49: 0x000000018e9fbae4 GraphicsServices`GSEventRunModal + 160
frame #50: 0x00000001852f02e4 UIKitCore`-[UIApplication _run] + 868
frame #51: 0x00000001852f3f5c UIKitCore`UIApplicationMain + 124
frame #52: 0x00000001c51fc1b0 SwiftUI`___lldb_unnamed_symbol205407 + 172
frame #53: 0x00000001c51fc050 SwiftUI`___lldb_unnamed_symbol205405 + 140
frame #54: 0x00000001c4f02fa4 SwiftUI`static SwiftUI.App.main() -> () + 80
frame #55: 0x000000010202b000 SwiftUIDemo`static SwiftUIDemoApp.$main(self=SwiftUIDemo.SwiftUIDemoApp) at <compiler-generated>:0
frame #56: 0x000000010202b0b0 SwiftUIDemo`main at SwiftUIDemoApp.swift:11:8
frame #57: 0x0000000102735544 dyld_sim`start_sim + 20
frame #58: 0x0000000102236058 dyld`start + 2224

backtrace (bt) 命令输出的调用栈信息的格式为【栈帧序号-内存地址-函数名-偏移量】,其中偏移量是该函数相对于该函数所在栈帧内存开始的偏移量(十进制)。

支持一下
扫一扫,支持forsigner
  • 微信扫一扫
  • 支付宝扫一扫