Hi Tom! On Fri, 8 Feb 2019 10:41:47 +0100, Tom de Vries <tdevr...@suse.de> wrote: > The backtrace functions backtrace_full, backtrace_print and backtrace_simple > walk the call stack, but make sure to skip the first entry, in order to skip > over the functions themselves, and start the backtrace at the caller of the > functions. > > When compiling with -flto, the functions may be inlined, causing them to skip > over the caller instead.
So, when recently working on the OpenACC Profiling Interface implementation in libgomp, where I'm using libbacktrace to figure out the caller of certain libgomp functions, I recently wondered about the very same issue, that we reliably have to skip a few initial frames. So, "noinline" is how to do that reliably... ;-/ That might be non-obvious for the casual reader, so they might not understand... > Fix this by declaring the functions with __attribute__((noinline)). ... this alone. I'd suggest to have a common "#define LIBBACKTRACE_NOINLINE [...]" (or similar), together with the explanatory comment given above, and use that at the respective definition (or declaration?) sites. Can that go into the public libbacktrace "*.h" file, so that it can also be used elsewhere, as described above? If you agree, want me to prepare a patch? Grüße Thomas > [libbacktrace] Declare external backtrace fns noinline > > 2019-02-08 Tom de Vries <tdevr...@suse.de> > > * backtrace.c (backtrace_full): Declare with __attribute__((noinline)). > * print.c (backtrace_print): Same. > * simple.c (backtrace_simple): Same. > > --- > libbacktrace/backtrace.c | 2 +- > libbacktrace/print.c | 2 +- > libbacktrace/simple.c | 2 +- > 3 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/libbacktrace/backtrace.c b/libbacktrace/backtrace.c > index 29204c63313..c579e803825 100644 > --- a/libbacktrace/backtrace.c > +++ b/libbacktrace/backtrace.c > @@ -98,7 +98,7 @@ unwind (struct _Unwind_Context *context, void *vdata) > > /* Get a stack backtrace. */ > > -int > +int __attribute__((noinline)) > backtrace_full (struct backtrace_state *state, int skip, > backtrace_full_callback callback, > backtrace_error_callback error_callback, void *data) > diff --git a/libbacktrace/print.c b/libbacktrace/print.c > index b2f45446443..0767facecae 100644 > --- a/libbacktrace/print.c > +++ b/libbacktrace/print.c > @@ -80,7 +80,7 @@ error_callback (void *data, const char *msg, int errnum) > > /* Print a backtrace. */ > > -void > +void __attribute__((noinline)) > backtrace_print (struct backtrace_state *state, int skip, FILE *f) > { > struct print_data data; > diff --git a/libbacktrace/simple.c b/libbacktrace/simple.c > index d439fcee8e2..118936397da 100644 > --- a/libbacktrace/simple.c > +++ b/libbacktrace/simple.c > @@ -90,7 +90,7 @@ simple_unwind (struct _Unwind_Context *context, void *vdata) > > /* Get a simple stack backtrace. */ > > -int > +int __attribute__((noinline)) > backtrace_simple (struct backtrace_state *state, int skip, > backtrace_simple_callback callback, > backtrace_error_callback error_callback, void *data)