有没有找到调用堆栈比使用回溯()的深度较便宜的方式?
题
我的记录代码使用的回溯(返回值)来确定当前堆栈深度(为漂亮的印刷的目的),但我可以从剖析,这是一个相当昂贵的呼叫见
我不认为有这样做的便宜的方式?请注意,我不关心帧的地址,只是他们中有多少有。
编辑:这些记录功能被使用的所有在大的代码的基础上,所以手动跟踪堆栈深度不是一个真正的选择
解决方案
走栈自己是相当快 - 最backtrace()
缓慢的是仰视的符号名。在x86上,你可以做到以下几点:
inline uint32_t get_ebp(void)
{
__asm__ __volatile__("mov %%ebp, %%eax");
}
int get_stack_depth(void)
{
uint32_t ebp = get_ebp();
int stack_depth = 0;
while(ebp != 0)
{
ebp = *(uint32_t *)ebp;
stack_depth++;
}
return stack_depth;
}
此将步行ebp
指针的链。请记住,这是非常不便于携带。还要注意的是,这将不计算已内联或尾调用优化(当然,backtrace()
具有相同的问题)。
另一个重要问题是终止条件 - 一旦你回溯高达main()
,经常有没有什么你将在堆栈找到担保。所以,如果libc中并没有把空帧指针,你很可能段错误。您可以通过main()
一开始看着它得到终止值。
其他提示
如果您的漂亮打印功能被合理地包含的,然后通过在缩进(或缩进大小)作为一个参数,并且只增加它当调用其它显示功能。
你就不能随身携带 TLS 变量,你所谓的“深度“并加/减它的每一个功能?虽然你可以编写自己的代码走栈更快,它仍然会比只携带变量周围,你慢。
有关臂结构:
register unsigned long *rfp asm("fp");
unsigned long *fp = rfp;
unsigned long depth = 0;
while(fp)
{
fp = (unsigned long *)(*(fp -3));
depth++;
}
return depth;
不隶属于 StackOverflow