[glib] gio: Add SystemTap and DTrace probes for GTask
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gio: Add SystemTap and DTrace probes for GTask
- Date: Thu, 16 Jun 2016 16:11:58 +0000 (UTC)
commit 195a0cb6bb8cc8739902fcf3245bfe256c980c60
Author: Philip Withnall <philip tecnocode co uk>
Date: Wed Dec 23 16:35:24 2015 +0000
gio: Add SystemTap and DTrace probes for GTask
This adds a basic tapset for GIO, covering various interesting parts of
GTask.
https://bugzilla.gnome.org/show_bug.cgi?id=759813
docs/reference/gio/Makefile.am | 1 +
docs/reference/glib/running.xml | 3 +-
gio/Makefile.am | 35 +++++++++++++
gio/gio.stp.in | 107 +++++++++++++++++++++++++++++++++++++++
gio/gio_probes.d | 10 ++++
gio/gio_trace.h | 41 +++++++++++++++
gio/gtask.c | 34 +++++++++++-
7 files changed, 227 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/gio/Makefile.am b/docs/reference/gio/Makefile.am
index 38666b4..ff201cd 100644
--- a/docs/reference/gio/Makefile.am
+++ b/docs/reference/gio/Makefile.am
@@ -51,6 +51,7 @@ IGNORE_HFILES = \
gfileattribute-priv.h \
gfileinfo-priv.h \
ghttpproxy.h \
+ gio_trace.h \
giomodule-priv.h \
gioprivate.h \
giowin32-priv.h \
diff --git a/docs/reference/glib/running.xml b/docs/reference/glib/running.xml
index a00369b..c05820b 100644
--- a/docs/reference/glib/running.xml
+++ b/docs/reference/glib/running.xml
@@ -310,7 +310,8 @@ Which would print the contents of each widget in a list of widgets.
<ulink url="http://sourceware.org/systemtap/">SystemTap</ulink> is a dynamic whole-system
analysis toolkit. GLib ships with a file <filename>glib.stp</filename> which defines a
set of probe points, which you can hook into with custom SystemTap scripts.
-See the files <filename>glib.stp</filename> and <filename>gobject.stp</filename> which
+See the files <filename>glib.stp</filename>, <filename>gobject.stp</filename>
+and <filename>gio.stp</filename> which
are in your shared SystemTap scripts directory.
</para>
diff --git a/gio/Makefile.am b/gio/Makefile.am
index e911d91..18e0ca1 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -391,6 +391,7 @@ libgio_2_0_la_SOURCES = \
ginetsocketaddress.c \
ginitable.c \
ginputstream.c \
+ gio_trace.h \
gioenums.h \
gioerror.c \
giomodule.c \
@@ -756,6 +757,40 @@ itsdir = $(datadir)/gettext/its
dist_its_DATA = gschema.loc gschema.its
# ------------------------------------------------------------------------
+# SystemTap and dtrace
+
+if ENABLE_DTRACE
+DTCOMPILE = $(patsubst -W%,,$(LTCOMPILE))
+DTCFLAGS = $(patsubst -W%,,$(CFLAGS))
+
+gio_probes.h: gio_probes.d
+ $(AM_V_GEN) $(DTRACE) -C -h -s $< -o $ tmp
+ @$(SED) -e "s,define STAP_HAS_SEMAPHORES 1,undef STAP_HAS_SEMAPHORES," < $ tmp > $@ && rm -f $ tmp
+
+gio_probes.lo: gio_probes.d
+ $(AM_V_GEN) env CC="$(DTCOMPILE)" CFLAGS="$(DTCFLAGS)" $(DTRACE) -G -s $< -o $@
+
+BUILT_SOURCES += gio_probes.h gio_probes.lo
+CLEANFILES += gio_probes.h gio_probes.h.tmp
+libgio_2_0_la_LIBADD += gio_probes.lo
+endif
+
+if ENABLE_SYSTEMTAP
+tapset_in_files = gio.stp.in
+tapsetdir = @ABS_TAPSET_DIR@
+tapset_DATA = $(tapset_in_files:.stp.in=.stp)
+EXTRA_DIST += $(tapset_in_files)
+CLEANFILES += $(tapset_in_files:.stp.in=.stp)
+
+$(tapset_DATA): %.stp: %.stp.in Makefile
+ $(AM_V_GEN)$(SED) \
+ -e 's|[ ]ABS_GLIB_RUNTIME_LIBDIR[@]|$(ABS_GLIB_RUNTIME_LIBDIR)|g' \
+ -e 's|[ ]LT_CURRENT[@]|$(LT_CURRENT)|g' \
+ -e 's|[ ]LT_REVISION[@]|$(LT_REVISION)|g' \
+ $< > $@
+endif
+
+# ------------------------------------------------------------------------
# gdbus(1) tool
bin_PROGRAMS += gdbus
diff --git a/gio/gio.stp.in b/gio/gio.stp.in
new file mode 100644
index 0000000..3ca0cd3
--- /dev/null
+++ b/gio/gio.stp.in
@@ -0,0 +1,107 @@
+/**
+ * probe gio.task_new - Called when a new #GTask is created
+ * @task: the new #GTask object
+ * @source_object: the source object
+ * @cancellable: the #GCancellable
+ * @callback: the task’s callback
+ * @callback_data: data for @callback
+ */
+probe gio.task_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__new")
+{
+ task = $arg1;
+ source_object = $arg2;
+ cancellable = $arg3;
+ callback = $arg4;
+ callback_data = $arg5;
+ probestr = sprintf("gio.task_new(%p, %p, %p, %p) -> %p", source_object, cancellable, callback,
callback_data, task);
+}
+
+/**
+ * probe gio.task_set_task_data - Called when the task data is set on a #GTask
+ * @task: the #GTask object
+ * @task_data: the task data
+ * @task_data_destroy: the destroy notify function for the data
+ */
+probe gio.task_set_task_data = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__set_task_data")
+{
+ task = $arg1;
+ task_data = $arg2;
+ task_data_destroy = $arg3;
+ probestr = sprintf("gio.task_set_task_data(%p, %p, %p)", task, task_data, task_data_destroy);
+}
+
+/**
+ * probe gio.task_set_priority - Called when the priority of a #GTask is set
+ * @task: the #GTask object
+ * @priority: the priority
+ */
+probe gio.task_set_priority = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__set_priority")
+{
+ task = $arg1;
+ priority = $arg2;
+ probestr = sprintf("gio.task_set_priority(%p, %i)", task, priority);
+}
+
+/**
+ * probe gio.task_set_source_tag - Called when the source tag of a #GTask is set
+ * @task: the #GTask object
+ * @source_tag: the source tag
+ */
+probe gio.task_set_source_tag = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__set_source_tag")
+{
+ task = $arg1;
+ source_tag = $arg2;
+ probestr = sprintf("gio.task_set_source_tag(%p, %p)", task, source_tag);
+}
+
+/**
+ * probe gio.task_before_return - Called before a #GTask invokes its callback or returns from
g_task_run_in_thread_sync()
+ * @task: the #GTask object
+ * @source_object: the source object passed to the callback
+ * @callback: the callback about to be invoked
+ * @callback_data: data passed to @callback
+ */
+probe gio.task_before_return = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__before_return")
+{
+ task = $arg1;
+ source_object = $arg2;
+ callback = $arg3;
+ callback_data = $arg4;
+ probestr = sprintf("gio.task_before_return(%p, %p, %p, %p)", task, source_object, callback, callback_data);
+}
+
+/**
+ * probe gio.task_propagate - Called when a #GTask’s result is propagated
+ * @task: the #GTask object
+ * @error_set: %TRUE if propagating an error, %FALSE otherwise
+ */
+probe gio.task_propagate = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__propagate")
+{
+ task = $arg1;
+ error_set = $arg2;
+ probestr = sprintf("gio.task_propagate(%p) -> %u", task, error_set);
+}
+
+/**
+ * probe gio.task_before_run_in_thread - Called before a #GTask’s function is run in a thread
+ * @task: the #GTask object
+ * @task_func: the task function being run
+ */
+probe gio.task_before_run_in_thread = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__before_run_in_thread")
+{
+ task = $arg1;
+ task_func = $arg2;
+ probestr = sprintf("gio.task_before_run_in_thread(%p, %p)", task, task_func);
+}
+
+/**
+ * probe gio.task_after_run_in_thread - Called after a #GTask’s function is run in a thread
+ * @task: the #GTask object
+ * @thread_cancelled: %TRUE if the thread was cancelled, %FALSE otherwise
+ */
+probe gio.task_after_run_in_thread = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2 0 so 0 LT_CURRENT@
LT_REVISION@").mark("task__after_run_in_thread")
+{
+ task = $arg1;
+ thread_cancelled = $arg2;
+ probestr = sprintf("gio.task_after_run_in_thread(%p) -> %u", task, thread_cancelled);
+}
diff --git a/gio/gio_probes.d b/gio/gio_probes.d
new file mode 100644
index 0000000..8747d8d
--- /dev/null
+++ b/gio/gio_probes.d
@@ -0,0 +1,10 @@
+provider gio {
+ probe task__new(void*, void*, void*, void*, void*);
+ probe task__set_task_data(void*, void*, void*);
+ probe task__set_priority(void*, int);
+ probe task__set_source_tag(void*, void*);
+ probe task__before_return(void*, void*, void*, void*);
+ probe task__propagate(void*, unsigned int);
+ probe task__before_run_in_thread(void*, void*);
+ probe task__after_run_in_thread(void*, unsigned int);
+};
diff --git a/gio/gio_trace.h b/gio/gio_trace.h
new file mode 100644
index 0000000..ba69a6e
--- /dev/null
+++ b/gio/gio_trace.h
@@ -0,0 +1,41 @@
+/* GLIB - Library of useful routines for C programming
+ *
+ * Copyright (C) 2009,2010 Red Hat, Inc.
+ *
+ * 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 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 Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ */
+
+#ifndef __GIOTRACE_H__
+#define __GIOTRACE_H__
+
+#ifndef SIZEOF_CHAR
+#error "config.h must be included prior to gio_trace.h"
+#endif
+
+#ifdef HAVE_DTRACE
+
+/* include the generated probes header and put markers in code */
+#include "gio_probes.h"
+#define TRACE(probe) probe
+
+#else
+
+/* Wrap the probe to allow it to be removed when no systemtap available */
+#define TRACE(probe)
+
+#endif
+
+#endif /* __GIOTRACE_H__ */
diff --git a/gio/gtask.c b/gio/gtask.c
index 042e047..4af4237 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -17,6 +17,7 @@
*/
#include "config.h"
+#include "gio_trace.h"
#include "gtask.h"
@@ -700,6 +701,9 @@ g_task_new (gpointer source_object,
if (source)
task->creation_time = g_source_get_time (source);
+ TRACE (GIO_TASK_NEW (task, source_object, cancellable,
+ callback, callback_data));
+
return task;
}
@@ -803,6 +807,8 @@ g_task_set_task_data (GTask *task,
task->task_data = task_data;
task->task_data_destroy = task_data_destroy;
+
+ TRACE (GIO_TASK_SET_TASK_DATA (task, task_data, task_data_destroy));
}
/**
@@ -825,6 +831,8 @@ g_task_set_priority (GTask *task,
gint priority)
{
task->priority = priority;
+
+ TRACE (GIO_TASK_SET_PRIORITY (task, priority));
}
/**
@@ -951,6 +959,8 @@ g_task_set_source_tag (GTask *task,
gpointer source_tag)
{
task->source_tag = source_tag;
+
+ TRACE (GIO_TASK_SET_SOURCE_TAG (task, source_tag));
}
/**
@@ -1101,6 +1111,9 @@ g_task_get_source_tag (GTask *task)
static void
g_task_return_now (GTask *task)
{
+ TRACE (GIO_TASK_BEFORE_RETURN (task, task->source_object, task->callback,
+ task->callback_data));
+
g_main_context_push_thread_default (task->context);
if (task->callback != NULL)
@@ -1219,6 +1232,8 @@ g_task_thread_complete (GTask *task)
return;
}
+ TRACE (GIO_TASK_AFTER_RUN_IN_THREAD (task, task->thread_cancelled));
+
task->thread_complete = TRUE;
g_mutex_unlock (&task->lock);
@@ -1338,6 +1353,8 @@ g_task_start_task_thread (GTask *task,
g_mutex_lock (&task->lock);
+ TRACE (GIO_TASK_BEFORE_RUN_IN_THREAD (task, task_func));
+
task->task_func = task_func;
if (task->cancellable)
@@ -1347,6 +1364,7 @@ g_task_start_task_thread (GTask *task,
&task->error))
{
task->thread_cancelled = task->thread_complete = TRUE;
+ TRACE (GIO_TASK_AFTER_RUN_IN_THREAD (task, task->thread_cancelled));
g_thread_pool_push (task_pool, g_object_ref (task), NULL);
return;
}
@@ -1453,6 +1471,10 @@ g_task_run_in_thread_sync (GTask *task,
g_mutex_unlock (&task->lock);
+ TRACE (GIO_TASK_BEFORE_RETURN (task, task->source_object,
+ NULL /* callback */,
+ NULL /* callback data */));
+
/* Notify of completion in this thread. */
task->completed = TRUE;
g_object_notify (G_OBJECT (task), "completed");
@@ -1491,18 +1513,24 @@ static gboolean
g_task_propagate_error (GTask *task,
GError **error)
{
+ gboolean error_set;
+
if (task->check_cancellable &&
g_cancellable_set_error_if_cancelled (task->cancellable, error))
- return TRUE;
+ error_set = TRUE;
else if (task->error)
{
g_propagate_error (error, task->error);
task->error = NULL;
task->had_error = TRUE;
- return TRUE;
+ error_set = TRUE;
}
else
- return FALSE;
+ error_set = FALSE;
+
+ TRACE (GIO_TASK_PROPAGATE (task, error_set));
+
+ return error_set;
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]