记录尚未完成的调用

函数甲调用乙,乙再调用丙时,甲与乙可能仍在等待后续结果。调用栈保留这些尚未完成的调用关系及所需状态,使当前调用结束后能够在相应位置继续。

一层调用常以栈帧呈现,但帧中放哪些参数、局部内容或返回资料取决于接口与实现。调用栈描述执行中的嵌套关系,不能与按词法位置组织的作用域直接等同。

参考:[1] [2]

回溯提供当前路径的证据

glibc的backtrace返回当前活动调用所对应的地址序列,符号化后可帮助定位函数与位置。Python的inspect则提供解释器帧和外层调用信息;这些接口描述的是各自环境可观察到的状态。

保留帧对象还可能保留其可访问的数据。Python文档提醒,帧引用可能形成循环并延长对象生命周期,所以诊断资料也有资源成本,不能假定取得栈信息永远没有副作用。

参考:[1] [2]

源码调用不保证各有物理帧

内联函数可能没有独立栈帧,尾调用优化也可让一个帧替换另一个。省略帧指针或缺少符号资料,还会影响某种回溯接口能恢复多少路径。

因此调试器显示的层数,不能不加条件地当作源码调用次数。递归深度、尾调用支持、异常展开和回溯工具都需结合实际运行环境解释,而不能仅依据“后进先出”四个字推断全部内存行为。

参考:[1] [2]