Bug 9956

Summary: Backtrace doesn't work in libubacktrace.so on MIPS
Product: uClibc Reporter: David Jarvie <djarvie>
Component: OtherAssignee: unassigned
Status: NEW ---    
Severity: normal CC: uclibc-cvs
Priority: P5    
Version: 0.9.33.2   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Host: Target:
Build:

Description David Jarvie 2017-06-14 15:24:55 UTC
On a MIPS 32 (mipsel) processor, calling backtrace() in libubacktrace.so doesn't produce any results - it returns a count of 0 stack frames. However, if the code in backtrace.c is copied into an application and built as part of the application, the backtrace() function works as expected.

I experimented quite a bit to try to get it to work, but have come to the conclusion that _Unwind_Backtrace() in libgcc_s.so doesn't properly handle what is pushed onto the stack when a call is made into the shared library libubacktrace.so before calling _Unwind_Backtrace() (but it does handle the call into libgcc_s.so correctly). So I think that there needs to be MIPS-specific code to manipulate the stack data in backtrace() before it calls _Unwind_Backtrace().

One issue seems to be that the pointer passed to backtrace() undergoes address translation, so that the pointer is wrong when it is passed to _Unwind_Backtrace(). (Called from backtrace() built into the application, there is no address translation when _Unwind_Backtrace() is called.) However, fixing that doesn't fix the problem.

Another thing I observed is that when backtrace() is called once, it is entered 4 times before returning, although there isn't any code to call it recursively. Presumably that's due in some way to how the stack is handled.

A minimum workaround for the issue is to copy the backtrace() function into the application. It can still use backtrace_helper() in the library, if 'static' is removed from that function's declaration.