2

I wanted to know if any porting is available for back trace implementation for uclibc in arm that I can use in my signal handler to debug segmentation faults.

I did come across a useful code here and tried using it inside my signal handler but it fails at the first check and returns from there.

I also tried a recurcive backtrace function which simply recursed using (current_frame_p)-3) till it was NULL and printed (current_frame_p)-1). This too seems to give me issues. All I get is the address of the handler and some garbage big address (I assume it might be the signal address). But I don't go beyond that. I want my trace to go beyond that.

The code that crashes is purposefully written for debug to dereference and invalid address.

Any help will be much appreciated.

Many many thanks in advance.

-Keshav

Community
  • 1
  • 1

2 Answers2

3

We are using the following code on an Arm device (glibc however). I have found this code couple of years ago (van't remember where exactly). It's working just fine without any problems.

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");


}

and

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;
}
osgx
  • 90,338
  • 53
  • 357
  • 513
avivl
  • 407
  • 4
  • 4
  • Thanks a ton Avivl. I wil ltry it and let you know if it works in uclibc as well. –  Nov 09 '10 at 05:08
  • Thanks a ton Avivl. I will try it and let you know if it works in uclibc as well. –  Nov 09 '10 at 06:14
  • 2
    what is struct layout and what are the parameters of the structure? – Mandar Jan 31 '12 at 09:54
0

I know the question was about uclibc, but I've found out how to get backtrace working with glibc now so I thought I'd say. Use "gcc -funwind-tables -rdynamic". The unwind-tables option makes libc:backtrace() work and the dynamic option makes libc:backtrace_symbols() work.

Alex Zeffertt
  • 1,462
  • 11
  • 12