我想知道是否有任何移植可用于uclibc的反向跟踪实现,我可以在我的信号处理程序中使用它来调试分段错误。
我确实遇到了一个有用的代码here并尝试在我的信号处理程序中使用它,但它在第一次检查时失败并从那里返回。
我还尝试了一个recurcive backtrace函数,它简单地使用(current_frame_p)-3)递归,直到它为NULL并打印(current_frame_p)-1)。这也似乎给了我一些问题。我得到的只是处理程序的地址和一些垃圾大地址(我假设它可能是信号地址)。但我不会超越这个。我希望我的追踪能够超越它。
崩溃的代码是故意编写的,用于调试取消引用和无效地址。
非常感谢任何帮助。
许多人提前感谢。
-Keshav
答案 0 :(得分:3)
我们在Arm设备上使用以下代码(但glibc)。 几年前我发现了这个代码(不记得到底在哪里)。 它没有任何问题,工作得很好。
void __printBacktrace(int skipCount,bool segv=false)
{
int * func_addresses[BACKTRACE_MAXDEPTH];
char demangle_output[1000];
int nfuncs = __arm_backtrace(func_addresses, BACKTRACE_MAXDEPTH );
printf("----- Start Stack Trace -----\n");
for (int i = skipCount; i < nfuncs; ++i)
{
Dl_info info;
if (dladdr(func_addresses[i], &info))
{
int dStat;
size_t dLength = 1000;
char * demangled = abi::__cxa_demangle(info.dli_sname,
demangle_output, &dLength, &dStat);
if (demangled && !dStat)
printf(
"return addr: %p: object:%s %p symbol:%s [%p+0x%x]\n",
func_addresses[i], info.dli_fname, info.dli_fbase,
demangled, info.dli_saddr, (int) func_addresses[i]
- (int) info.dli_saddr);
else
printf(
"return addr: %p: object:%s %p symbol:%s [%p+0x%x]\n",
func_addresses[i], info.dli_fname, info.dli_fbase,
info.dli_sname, info.dli_saddr, (int) func_addresses[i]
- (int) info.dli_saddr);
} else
fprintf(fCrash, "return addr: %p\n", func_addresses[i]);
}
printf("----- End Stack Trace -----\n");
}
和
int __arm_backtrace(int **arr, int maxsize)
{
int cnt = 0;
void *fp = __builtin_frame_address(0);
struct layout *lp = (struct layout *) ((char*) fp - 12);
while (cnt < maxsize)
{
arr[cnt++] = (int *) lp->return_address;
if (!lp->next)
{
break;
}
lp = lp->next - 1;
}
return cnt;
}
答案 1 :(得分:0)
我知道这个问题是关于uclibc的,但是我已经找到了如何使用glibc进行回溯,所以我想我会说。使用“gcc -funwind-tables -rdynamic”。 unwind-tables选项使libc:backtrace()工作,动态选项使libc:backtrace_symbols()工作。