Discussion:
[Libunwind-devel] ppc32 - stack trace limited when optimising -O2
Amit Chaudhuri
2018-06-02 09:18:24 UTC
Permalink
Hi again,

I am experimenting with libunwind on a embedded ppc32 system. At the
moment I just want to do a native, local unwind using a statically
linked demo app. If I compile that test app with the commonly used
defaults of -g -O2 I only see main and__libc_start_main. If I specify
-g -O0 I get the expected result (correct, deeper back trace).

Ultimately, I want to unwind an application that has been built
with optimisation turned up to -O3, so this is a bad result for me
just now.

Being a little unclear about whether to use libunwind.h/libunwind.a
or the -ppc32 suffixed version, I can readily believe I'm doing something
wrong. I've opted for the suffixed versions. Is what I am seeing expected
behaviour? A colleague tells me that using backtrace_symbols from libc
works at -O3. The libc docs suggest that linker options and optimisation
can both cause issues.

I *think* my use case is "local unwind" and so the call to unw_init_local
is appropriate.

I recall from earlier that support for ppc32 wasn't headlined in the
docs in the way pp64 was; is there a limitation to ppc32 that I'm
running into?

My configuration of libunwind gave --host=ppc-linux-gnu and CFLAGS
of -g -O2. Other options pointed to tools like ppc_82xx-strip etc.

Regards,

Amit

A summary of the outputs is here:

// compiled with -O2 linked to libunwind-ppc32.a

***@BTNetrix1601437508:/tmp# ./unwinder
in bar
in foo - call backtrace here
0x10000378: (main+0x10)
0x1000d160: (__libc_start_main+0x178)

// compiled with -O0 linked to libunwind-ppc32.a

***@BTNetrix1601437508:/tmp# ./unwinder
in bar
in foo - call backtrace here
0x10000354: (foo+0x28)
0x10000394: (bar+0x28)
0x100003cc: (main+0x20)
0x1000d1c0: (__libc_start_main+0x178)



The test app and it's origin are here:

// Example app from https://eli.thegreenplace.net \
/2015/programmatic-access-to-the-call-stack-in-c/

#include <libunwind-ppc32.h> // was libunwind.h
#include <stdio.h>

// Call this function to get a backtrace.
void backtrace() {
unw_cursor_t cursor;
unw_context_t context;

// Initialize cursor to current frame for local unwinding.
unw_getcontext(&context);
unw_init_local(&cursor, &context);

// Unwind frames one by one, going up the frame stack.
while (unw_step(&cursor) > 0) {
unw_word_t offset, pc;
unw_get_reg(&cursor, UNW_REG_IP, &pc);
if (pc == 0) {
break;
}
printf("0x%lx:", pc);

char sym[256];
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
printf(" (%s+0x%lx)\n", sym, offset);
} else {
printf(" -- error: unable to obtain symbol name for this frame\n");
}
}
}

void foo() {
printf("in foo - call backtrace here\n");
backtrace(); // <-------- backtrace here!
}

void bar() {
printf("in bar\n");
foo();
}

int main(int argc, char **argv) {
bar();

return 0;
}

Loading...