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-0002.html>
More information about the users
mailing list