This commit is contained in:
Christian Hergert 2023-02-21 14:30:58 -08:00
parent 378f1421f0
commit df80f432f0
5 changed files with 124 additions and 15 deletions

81
gdk/backtrace-helper.h Normal file
View File

@ -0,0 +1,81 @@
/* backtrace-helper.h
*
* Copyright 2020-2023 Christian Hergert <chergert@redhat.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
#include <sysprof-capture.h>
#ifdef HAVE_EXECINFO_H
# include <execinfo.h>
#endif
#ifdef ENABLE_LIBUNWIND
# define UNW_LOCAL_ONLY
# include <libunwind.h>
#endif
static void
backtrace_init (void)
{
#ifdef ENABLE_LIBUNWIND
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
# ifdef HAVE_UNW_SET_CACHE_SIZE
unw_set_cache_size (unw_local_addr_space, 1024, 0);
#endif
#endif
}
static int
backtrace_func (SysprofCaptureAddress *addrs,
guint n_addrs,
G_GNUC_UNUSED gpointer user_data)
{
#if defined(ENABLE_LIBUNWIND)
# if GLIB_SIZEOF_VOID_P == 8
/* 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 - 2, n_addrs) - 2;
# else
static const int skip = 2;
void **stack = alloca (n_addrs * sizeof (gpointer));
int 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
/* See note on unw_backtrace() */
return backtrace ((void **)addrs - 2, n_addrs) - 2;
# else /* GLIB_SIZEOF_VOID_P != 8 */
static const int skip = 2;
void **stack = alloca (n_addrs * sizeof (gpointer));
int n = 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 /* GLIB_SIZEOF_VOID_P */
#else
return 0;
#endif
}

View File

@ -32,6 +32,9 @@
#include "gdkversionmacros.h"
#include "gdkframeclockprivate.h"
#ifdef HAVE_SYSPROF
# include "backtrace-helper.h"
#endif
gboolean
gdk_profiler_is_running (void)
@ -160,3 +163,19 @@ void
sysprof_collector_set_counters (&id, &value, 1);
#endif
}
void
(gdk_profiler_add_stacktrace) (void)
{
#ifdef HAVE_SYSPROF
static gsize did_init;
if (!did_init)
{
did_init = TRUE;
backtrace_init ();
}
sysprof_collector_sample (backtrace_func, NULL);
#endif
}

View File

@ -63,6 +63,8 @@ void gdk_profiler_end_markf (gint64 begin_time,
const gchar *message_format,
...) G_GNUC_PRINTF (3, 4);
void gdk_profiler_add_stacktrace (void);
guint gdk_profiler_define_counter (const char *name,
const char *description);
guint gdk_profiler_define_int_counter (const char *name,
@ -86,6 +88,8 @@ void gdk_profiler_set_int_counter (guint id,
/* no varargs macro support; the call will have to be optimised out by the compiler */
#endif
#define gdk_profiler_add_stacktrace() G_STMT_START {} G_STMT_END
#define gdk_profiler_define_counter(n, d) 0
#define gdk_profiler_define_int_counter(n, d) 0
#define gdk_profiler_set_counter(i, v) G_STMT_START {} G_STMT_END

View File

@ -27,6 +27,8 @@
#include "gtkrangeprivate.h"
#include "gdkprofilerprivate.h"
#include "gtkaccessible.h"
#include "gtkaccessiblerange.h"
#include "gtkadjustmentprivate.h"
@ -2348,6 +2350,8 @@ gtk_range_adjustment_changed (GtkAdjustment *adjustment,
double upper = gtk_adjustment_get_upper (priv->adjustment);
double lower = gtk_adjustment_get_lower (priv->adjustment);
gdk_profiler_add_stacktrace ();
gtk_widget_set_visible (priv->slider_widget, upper != lower || !GTK_IS_SCALE (range));
gtk_widget_queue_allocate (priv->trough_widget);

View File

@ -156,6 +156,7 @@ check_headers = [
'crt/externs.h',
'dev/evdev/input.h',
'dlfcn.h',
'execinfo.h',
'ftw.h',
'inttypes.h',
'linux/input.h',