Amit Chaudhuri
2018-06-02 09:18:24 UTC
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;
}
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;
}