【发布时间】:2021-05-15 19:09:51
【问题描述】:
当我尝试 google 时,我发现的只是有关获取和设置堆栈限制的内容,例如 -[NSThread stackSize],但这不是我想要的。我想知道当前线程的堆栈上实际使用了多少内存,或者等效地有多少堆栈空间可用。
我希望在用户提交的崩溃报告中找出堆栈溢出。在我之前的经验中,堆栈溢出通常是由无限递归引起的,但这次不是。所以我想知道我的一些 C++ 函数是否真的使用了比它们应有的更多的堆栈空间。
一条评论建议我在线程开始时获取堆栈指针,然后比较它的值。我碰巧遇到了问题Print out value of stack pointer。它有几个答案:
- (接受的答案)获取局部变量的地址。
- 使用一点汇编语言来获取堆栈指针寄存器的值。
- 在 GCC 或 Clang 中使用函数
__builtin_frame_address(0)。
我尝试了这些技术(Apple Clang,macOS 11.2)。方法 2 和 3 产生了相似的结果,但方法 1 产生了非常不同的结果。一方面,方法 1 给出的值会随着您深入调用链而增加,而其他方法给出的值会减少。这是怎么回事,有两种不同的堆栈吗?
【问题讨论】:
-
未测试,但您可以
pthread_attr_getstack()并与堆栈指针的当前值进行比较吗? -
或者你可以在线程第一次启动时将堆栈指针的值保存在线程本地存储中,稍后再进行比较。
-
@NateEldredge,我尝试了
pthread_attr_getstack,它返回 NULL 作为 stackaddr 参数,并且没有错误。这对我来说没有任何意义。 -
x86 和 arm64 上的堆栈增长了,不,没有两种。如果方法 #1 显示的数字上升,那么要么是您的测试代码有问题,要么是编译器优化正在影响它。你能展示你的测试用例吗?
-
@NateEldredge 你是对的,这是一个编译器设置:地址清理器 (ASAN) 带有选项“检测返回后使用堆栈”会导致方法 #1 中的奇怪值。