有没有找到调用堆栈比使用回溯()的深度较便宜的方式? [英] Is there a cheaper way to find the depth of the call stack than using backtrace()?
问题描述
我的日志code使用的回溯(),以确定返回值当前堆栈深度(为pretty印刷的目的),但我可以从分析,这是一个pretty昂贵的调用看看。
My logging code uses the return value of backtrace() to determine the current stack depth (for pretty printing purposes), but I can see from profiling that this is a pretty expensive call.
我不认为有这样做的便宜的方式?请注意,我不关心帧的地址,只是其中有多少有。
I don't suppose there's a cheaper way of doing this? Note that I don't care about the frame addresses, just how many of them there are.
编辑:这些日志记录功能使用的所有在大code-基地,使手动跟踪堆栈深度是不是一个真正的选择。
edit: These logging functions are used all over a large code-base, so manually tracking the stack depth isn't really an option.
推荐答案
走栈自己是pretty快 - 在回溯最缓慢的()
是从仰视的符号名。在x86上,你可以做到以下几点:
Walking the stack yourself is pretty quick - most of the slowness in backtrace()
is from looking up symbol names. On x86, you can do the following:
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
指针链。请记住,这是非常不便于携带。请注意,这将不计入已内联或尾调用优化的任何职能(当然,回溯()
有同样的问题)。
This will walk the chain of ebp
pointers. Keep in mind that this is extremely non-portable. Also note that this will not count any functions which have been inlined or tail-call optimized (of course, backtrace()
has the same problem).
另一个重要问题是终止条件 - 一旦你回溯到的main()
,也往往不是什么,你会在堆栈中找到的保证。所以,如果libc中并没有把空帧指针,你很可能会段错误。您可以在一开始就的main()
。
Another important issue is the termination condition -- once you backtrace up to main()
, there often aren't guarantees about what you'll find in the stack. So, if libc doesn't put a null frame pointer, you'll very likely segfault. You can get the termination value by looking at it at the very beginning of main()
.
这篇关于有没有找到调用堆栈比使用回溯()的深度较便宜的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!