libsysprof-capture: allow for backtrace skip optimization

We want to be backtracing directly into the capture buffer, but also need
to skip a small number of frames.

If we call the backtrace before filling in information, we can capture to
the position *before* ev->addrs and then overwrite that data right after.
This commit is contained in:
Christian Hergert
2020-02-18 13:35:18 -08:00
parent b6dc058d62
commit 70bea64f88
2 changed files with 26 additions and 10 deletions

View File

@ -77,17 +77,24 @@ backtrace_func (SysprofCaptureAddress *addrs,
{
#if defined(ENABLE_LIBUNWIND)
# if GLIB_SIZEOF_VOID_P == 8
return unw_backtrace ((void **)addrs, n_addrs);
/* We know that collector will overwrite fields *AFTER* it
* has called the backtrace function allowing us to cheat
* and subtract an offset from addrs to avoid having to
* copy frame pointers around.
*/
return unw_backtrace ((void **)addrs - 1, n_addrs);
# else
static const gint skip = 1;
void **stack = alloca (n_addrs * sizeof (gpointer));
guint n = unw_backtrace (stack, n_addrs);
for (guint i = 0; i < n; i++)
addrs[i] = GPOINTER_TO_SIZE (stack[i]);
return n;
gint n = unw_backtrace (stack, n_addrs);
for (guint i = skip; i < n; i++)
addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]);
return MAX (0, n - skip);
# endif
#elif defined(HAVE_EXECINFO_H)
# if GLIB_SIZEOF_VOID_P == 8
return backtrace ((void **)addrs, n_addrs);
/* See note on unw_backtrace() */
return backtrace ((void **)addrs - 1, n_addrs);
# else /* GLIB_SIZEOF_VOID_P != 8 */
void **stack = alloca (n_addrs * sizeof (gpointer));
guint n = backtrace (stack, n_addrs);