How to generate meaningfull stacktraces with RTEMS on the Leon3

Matthew J Fletcher amimjf at gmail.com
Wed Dec 7 12:30:11 UTC 2016


Hi,

The gcc builtin functions (and libunwind) and only work if the stack frame
information is not optimised away, this is controlled by gcc compiler
flags, see; https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
-fomit-frame-pointer

Without that you have to do your own unwinding, for example on x86 you
could do the following, but its pretty crude. Linux/FreeBSD do much more
fancy unwinders, it depends on what you want.

#define get_ebp()       \
({ unsigned long  __value;   \
   asm volatile (" mov %%ebp,%0": "=a"(__value));  \
   __value; })

void error_dump_callstack(int fd)
{
unsigned long ebp=0,arg0,arg4,arg8,arg12,arg16;
int i;

arg0 = get_ebp(); // base pointer, start of current stack frame

assert_out(fd,"\r\nCall Stack Information:\r\n\r\n");
for (i=0; i<15; i++)
{
// attempt get backtrace (with arguments) from stored EPB
arg0 = *(unsigned long*)(arg0);

if (arg0 == 0)
break;

// print stackframe back past inturrupt
arg0 = *(unsigned long*)(arg0);
arg4 = *(unsigned long*)(arg0+4);
arg8 = *(unsigned long*)(arg0+8);
arg12 = *(unsigned long*)(arg0+12);
arg16 = *(unsigned long*)(arg0+16);
sprintf(assertbuffer,"ebp:     %p\r\nframe%d:  %p\r\narg1:    %p\r\narg2:
 %p\r\narg3:    %p\r\n",arg0,i,arg4,arg8,arg12,arg16);
assert_out(fd,assertbuffer);
}
assert_out(fd,"use 'addr2line -C -e abc.elf -f address' to get symbol
names\r\n");
}





On 6 December 2016 at 22:36, Chris Johns <chrisj at rtems.org> wrote:

> On 06/12/2016 01:46, Jan Sommer wrote:
>
>> Is there a common way how to create stacktraces in RTEMS?
>>
>
> Not that I know of.
>
> I tried to use the _Unwind_Backtrace_-function from gcc, but so far it
>> only returns _URC_END_OF_STACK if I call it from a leaf function
>> (haven't tried a trap handler yet).
>>
>
> The end of stack code means the unwinder could not find any data about the
> frames in the stack. The default DWARF unwinder, which SPARC uses, searches
> for a valid Frame Description Entry (FDE) and if not found reports the end
> of stack code. If an FDE is found the Common Information Entry (CIE) is
> extracted from that data and the frame info decoded.
>
> C++ uses the same process for exceptions. A .eh_frame plus some other
> sections are created and the frames effected by the exceptions added to
> these sections. These sections are registered at start up. For a DWARF
> unwinder, which includes the SPARC, the DWARF standard is used for the
> format of these sections.
>
> I am not sure if that is the way to go.
>>
>
> I am not 100% sure myself. I think you would need to include some level of
> DWARF related information in the executable to do this. This information
> would need to be registered with the DWARF unwinder code via something like
> 'void __register_frame (void *begin)'.
>
> I would also take a look at FreeBSD and see how they implement the
> unwinder. I do not know if the FreeBSD kernel has one.
>
> Are there any recommendations or examples for this topic?
>>
>
> The DWARF standard website is the best source of info:
>
> http://dwarfstd.org/
>
> Chris
>
> _______________________________________________
> users mailing list
> users at rtems.org
> http://lists.rtems.org/mailman/listinfo/users
>



-- 

regards
---
Matthew J Fletcher
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20161207/5799cc57/attachment.html>


More information about the users mailing list