我们在ARM 9上运行uclibc linux。问题是uclibc不支持回溯。发生核心转储时,我无法获取调用堆栈。任何移植可用于uclibc回溯?
有没有人有一个很好的解决方案呢?
例如,现有的uclibc回溯移植,或者在发生核心转储时抓取调用堆栈的好方法(uclibc + ARM + Linux)?
我们在ARM 9上运行uclibc linux。问题是uclibc不支持回溯。发生核心转储时,我无法获取调用堆栈。任何移植可用于uclibc回溯?
有没有人有一个很好的解决方案呢?
例如,现有的uclibc回溯移植,或者在发生核心转储时抓取调用堆栈的好方法(uclibc + ARM + Linux)?
更新:
看来,一个patch的设立是为了支持uClibc的backtrace()
适用于x86和ARM(XScale的),它利用了__libc_stack_end
象征。
原来的答案:
我曾在那里的版本中,我们使用没有提供我们的ARM处理器的功能backtrace()
的glibc的,所以我们用开发了自己的glibc之外的项目__libc_stack_end
符号。以下是最终的代码。也许你可以用它来写一个uclibc backtrace()
函数。
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
你应该把这个帖子的信息放到你的答案里,否则当这个链接404s的时候,你的答案变得毫无用处。 – 2012-07-16 17:24:33
好的。做了一个git commit的链接。 – lumpidu 2012-08-07 12:19:21
从上面的代码我得到运行时错误“回溯错误:__builtin_return_address(0)!= frame_p-> lr“。如何解决这种情况。 – Mandar 2012-01-31 08:54:29
标准ARM调用约定([pdf链接](http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf))分配r14作为链接寄存器。在子程序调用中使用的BL指令将返回地址存储在该寄存器中。 '__builtin_frame_address(0)'和'__builtin_return_address(0)'函数用于[获取调用函数的返回值和帧地址](http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html )。你的错误表示链接寄存器不包含返回地址,或者'backtrace_frame_t'结构与你的堆栈帧不匹配。 – jschmier 2012-01-31 15:31:32