Any porting available of backtrace for uclibc?
Asked Answered
T

2

10

We are running the uclibc linux on ARM 9. The problem is uclibc doesn't support backtrace. When a core dump happens, I cannot grab the call stack.

Does anyone have a good solution for that?

For example, an existing porting of backtrace for uclibc, or any good method to grab the call stack when a core dump happens (uclibc+ARM+Linux)?

Tainataint answered 29/3, 2010 at 5:57 Comment(0)
F
5

Update:

It seems that a patch was created to support backtrace() on uclibc for x86 and ARM (XScale) and it makes use of the __libc_stack_end symbol.


Original Answer:

I worked on a project where the version of glibc we were using did not provide a functional backtrace() for our ARM processor, so we developed our own outside of glibc using the __libc_stack_end symbol. Below is the resulting code. Perhaps you can use it to write a uclibc backtrace() function.

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;
}

Note: The __libc_stack_end symbol is no longer exported in more recent versions of glibc and I'm not sure of the existence of it or a similar symbol in uclibc.

Franciscafranciscan answered 29/3, 2010 at 6:32 Comment(2)
from the above code i am getting runtime error "backtrace error: __builtin_return_address(0) != frame_p->lr" . how to resolve this condition.Swee
The standard ARM calling convention (pdf link) allocates r14 as the link register. The BL instruction, used in a subroutine call, stores the return address in this register. The __builtin_frame_address(0) and __builtin_return_address(0) functions are used for getting the return and frame address of the calling function. Your error says the link register doesn't contain the return address or the backtrace_frame_t structure doesn't match your stack frame.Franciscafranciscan
W
1

Have a look at the same question asked here:

http://lists.uclibc.org/pipermail/uclibc/2010-June/044115.html

which mentions a patch from here:

http://git.stlinux.com/?p=stm/uclibc.git;a=commit;h=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3

Whereof answered 11/11, 2010 at 13:55 Comment(1)
You should put the information from that post into your answer here, otherwise when that link 404s, your answer becomes useless.Scalping

© 2022 - 2024 — McMap. All rights reserved.