我们在 ARM 9 上运行 uclibc linux。问题是 uclibc 不支持回溯。当核心转储发生时,我无法获取调用堆栈。
有没有人有一个好的解决方案?
例如,现有的 uclibc 回溯移植,或者在发生核心转储时获取调用堆栈的任何好方法(uclibc+ARM+Linux)?
我们在 ARM 9 上运行 uclibc linux。问题是 uclibc 不支持回溯。当核心转储发生时,我无法获取调用堆栈。
有没有人有一个好的解决方案?
例如,现有的 uclibc 回溯移植,或者在发生核心转储时获取调用堆栈的任何好方法(uclibc+ARM+Linux)?
更新:
似乎创建了一个补丁来支持backtrace()
uclibc for x86 和 ARM (XScale),它使用了该__libc_stack_end
符号。
原答案:
我在一个项目中工作,我们使用的 glibc 版本没有backtrace()
为我们的 ARM 处理器提供功能,所以我们使用该__libc_stack_end
符号在 glibc 之外开发了我们自己的。下面是生成的代码。也许你可以用它来写一个 uclibcbacktrace()
函数。
extern void * __libc_stack_end;
struct backtrace_frame_t
{
void * fp;
void * sp;
void * lr;
void * pc;
};
int backtrace(void ** array, int size)
{
void * top_frame_p;
void * current_frame_p;
struct backtrace_frame_t * frame_p;
int frame_count;
top_frame_p = __builtin_frame_address(0);
current_frame_p = top_frame_p;
frame_p = (struct backtrace_frame_t*)((void**)(current_frame_p)-3);
frame_count = 0;
if (__builtin_return_address(0) != frame_p->lr)
{
fprintf(stderr, "backtrace error: __builtin_return_address(0) != frame_p->lr\n");
return frame_count;
}
if (current_frame_p != NULL
&& current_frame_p > (void*)&frame_count
&& current_frame_p < __libc_stack_end)
{
while (frame_count < size
&& current_frame_p != NULL
&& current_frame_p > (void*)&frame_count
&& current_frame_p < __libc_stack_end)
{
frame_p = (struct backtrace_frame_t*)((void**)(current_frame_p)-3);
array[frame_count] = frame_p->lr;
frame_count++;
current_frame_p = frame_p->fp;
}
}
return frame_count;
}
注意:该__libc_stack_end
符号不再在更新版本的 glibc 中导出,我不确定它或 uclibc 中是否存在类似符号。
看看这里问的同样的问题:
http://lists.uclibc.org/pipermail/uclibc/2010-June/044115.html
其中提到了此处的补丁:
http://git.stlinux.com/?p=stm/uclibc.git;a=commit;h=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3