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 "gdkversionmacros.h"
#include "gdkframeclockprivate.h" #include "gdkframeclockprivate.h"
#ifdef HAVE_SYSPROF
# include "backtrace-helper.h"
#endif
gboolean gboolean
gdk_profiler_is_running (void) gdk_profiler_is_running (void)
@ -160,3 +163,19 @@ void
sysprof_collector_set_counters (&id, &value, 1); sysprof_collector_set_counters (&id, &value, 1);
#endif #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, const gchar *message_format,
...) G_GNUC_PRINTF (3, 4); ...) G_GNUC_PRINTF (3, 4);
void gdk_profiler_add_stacktrace (void);
guint gdk_profiler_define_counter (const char *name, guint gdk_profiler_define_counter (const char *name,
const char *description); const char *description);
guint gdk_profiler_define_int_counter (const char *name, 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 */ /* no varargs macro support; the call will have to be optimised out by the compiler */
#endif #endif
#define gdk_profiler_add_stacktrace() G_STMT_START {} G_STMT_END
#define gdk_profiler_define_counter(n, d) 0 #define gdk_profiler_define_counter(n, d) 0
#define gdk_profiler_define_int_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 #define gdk_profiler_set_counter(i, v) G_STMT_START {} G_STMT_END

View File

@ -20,13 +20,15 @@
* Modified by the GTK+ Team and others 1997-2004. See the AUTHORS * Modified by the GTK+ Team and others 1997-2004. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog * file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with * files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#include "config.h" #include "config.h"
#include "gtkrangeprivate.h" #include "gtkrangeprivate.h"
#include "gdkprofilerprivate.h"
#include "gtkaccessible.h" #include "gtkaccessible.h"
#include "gtkaccessiblerange.h" #include "gtkaccessiblerange.h"
#include "gtkadjustmentprivate.h" #include "gtkadjustmentprivate.h"
@ -688,7 +690,7 @@ gtk_range_set_adjustment (GtkRange *range,
priv->adjustment = adjustment; priv->adjustment = adjustment;
g_object_ref_sink (adjustment); g_object_ref_sink (adjustment);
g_signal_connect (adjustment, "changed", g_signal_connect (adjustment, "changed",
G_CALLBACK (gtk_range_adjustment_changed), G_CALLBACK (gtk_range_adjustment_changed),
range); range);
@ -1069,7 +1071,7 @@ gtk_range_set_range (GtkRange *range,
GtkRangePrivate *priv = gtk_range_get_instance_private (range); GtkRangePrivate *priv = gtk_range_get_instance_private (range);
GtkAdjustment *adjustment; GtkAdjustment *adjustment;
double value; double value;
g_return_if_fail (GTK_IS_RANGE (range)); g_return_if_fail (GTK_IS_RANGE (range));
g_return_if_fail (min <= max); g_return_if_fail (min <= max);
@ -1548,7 +1550,7 @@ clamp_dimensions (int range_width,
*width += extra; *width += extra;
} }
} }
/* See if we can fit rect, if not kill the border */ /* See if we can fit rect, if not kill the border */
shortage = *width - range_width; shortage = *width - range_width;
if (shortage > 0) if (shortage > 0)
@ -1585,7 +1587,7 @@ clamp_dimensions (int range_width,
border->bottom += extra / 2 + extra % 2; border->bottom += extra / 2 + extra % 2;
} }
} }
/* See if we can fit rect, if not kill the border */ /* See if we can fit rect, if not kill the border */
shortage = *height - range_height; shortage = *height - range_height;
if (shortage > 0) if (shortage > 0)
@ -2348,6 +2350,8 @@ gtk_range_adjustment_changed (GtkAdjustment *adjustment,
double upper = gtk_adjustment_get_upper (priv->adjustment); double upper = gtk_adjustment_get_upper (priv->adjustment);
double lower = gtk_adjustment_get_lower (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_set_visible (priv->slider_widget, upper != lower || !GTK_IS_SCALE (range));
gtk_widget_queue_allocate (priv->trough_widget); gtk_widget_queue_allocate (priv->trough_widget);
@ -2391,7 +2395,7 @@ gtk_range_adjustment_value_changed (GtkAdjustment *adjustment,
} }
static void static void
apply_marks (GtkRange *range, apply_marks (GtkRange *range,
double oldval, double oldval,
double *newval) double *newval)
{ {
@ -2502,7 +2506,7 @@ gtk_range_scroll (GtkRange *range,
else else
step_back (range); step_back (range);
break; break;
case GTK_SCROLL_STEP_UP: case GTK_SCROLL_STEP_UP:
if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) if (should_invert_move (range, GTK_ORIENTATION_VERTICAL))
step_forward (range); step_forward (range);
@ -2516,18 +2520,18 @@ gtk_range_scroll (GtkRange *range,
else else
step_forward (range); step_forward (range);
break; break;
case GTK_SCROLL_STEP_DOWN: case GTK_SCROLL_STEP_DOWN:
if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) if (should_invert_move (range, GTK_ORIENTATION_VERTICAL))
step_back (range); step_back (range);
else else
step_forward (range); step_forward (range);
break; break;
case GTK_SCROLL_STEP_BACKWARD: case GTK_SCROLL_STEP_BACKWARD:
step_back (range); step_back (range);
break; break;
case GTK_SCROLL_STEP_FORWARD: case GTK_SCROLL_STEP_FORWARD:
step_forward (range); step_forward (range);
break; break;
@ -2538,7 +2542,7 @@ gtk_range_scroll (GtkRange *range,
else else
page_back (range); page_back (range);
break; break;
case GTK_SCROLL_PAGE_UP: case GTK_SCROLL_PAGE_UP:
if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) if (should_invert_move (range, GTK_ORIENTATION_VERTICAL))
page_forward (range); page_forward (range);
@ -2552,18 +2556,18 @@ gtk_range_scroll (GtkRange *range,
else else
page_forward (range); page_forward (range);
break; break;
case GTK_SCROLL_PAGE_DOWN: case GTK_SCROLL_PAGE_DOWN:
if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) if (should_invert_move (range, GTK_ORIENTATION_VERTICAL))
page_back (range); page_back (range);
else else
page_forward (range); page_forward (range);
break; break;
case GTK_SCROLL_PAGE_BACKWARD: case GTK_SCROLL_PAGE_BACKWARD:
page_back (range); page_back (range);
break; break;
case GTK_SCROLL_PAGE_FORWARD: case GTK_SCROLL_PAGE_FORWARD:
page_forward (range); page_forward (range);
break; break;
@ -2853,7 +2857,7 @@ _gtk_range_set_stop_values (GtkRange *range,
priv->n_marks = n_values; priv->n_marks = n_values;
for (i = 0; i < n_values; i++) for (i = 0; i < n_values; i++)
priv->marks[i] = values[i]; priv->marks[i] = values[i];
gtk_range_calc_marks (range); gtk_range_calc_marks (range);

View File

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