GVariant: add probes for SystemTap

https://bugzilla.gnome.org/show_bug.cgi?id=662779
Fixes: #473
This commit is contained in:
Allison Karlitskaya 2011-10-26 12:00:42 -04:00 committed by Philip Withnall
parent 9cb52d9f3b
commit 55abdd5e4a
4 changed files with 238 additions and 0 deletions

View File

@ -1,4 +1,5 @@
global glib_quarks_2_0_@LT_CURRENT@_@LT_REVISION@ global glib_quarks_2_0_@LT_CURRENT@_@LT_REVISION@
global gvarianttypeinfo_2_0_@LT_CURRENT@_@LT_REVISION@
/* This is needed to keep track of gquark for use in other probes.*/ /* This is needed to keep track of gquark for use in other probes.*/
probe process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("quark__new") probe process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("quark__new")
@ -643,3 +644,205 @@ probe glib.rcbox_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_
mem = $arg1; /* ARG: @mem: Raw memory pointer */ mem = $arg1; /* ARG: @mem: Raw memory pointer */
probestr = sprintf("glib.rcbox_free(mem=%p)", mem); probestr = sprintf("glib.rcbox_free(mem=%p)", mem);
} }
/**
* probe glib.variant_type_info_new:
* @info: Raw info structure pointer
* @typestr: GVariant type string
**/
probe glib.variant_type_info_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__type_info_new")
{
info = $arg1;
typestr = user_string($arg2);
gvarianttypeinfo[pid(), info] = typestr;
}
/**
* probe glib.variant_type_info_free:
* @info: Raw info structure pointer
**/
probe glib.variant_type_info_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__type_info_free")
{
info = $arg1;
delete gvarianttypeinfo[pid(), info];
}
/**
* probe glib.variant_start_serialise:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
*
* Indicates that a @value has started the process of serialising
* itself. This involves dropping references on the child elements of
* @value, so when mixed with the end_serialise probe, it is possible to
* see the context in which the unrefs are occuring.
**/
probe glib.variant_start_serialise = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__start_serialise")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
}
/**
* probe glib.variant_end_serialise:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
*
* Indicates that a @value has ended the process of serialising itself.
**/
probe glib.variant_end_serialise = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__end_serialise")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
}
/**
* probe glib.variant_from_buffer:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the initial reference count
* @state: the internal state bitfield
*
* Reports that a serialised #GVariant has been created from a buffer.
* This can happen in two cases. The first is when a leaf value is
* created (with g_variant_new_string(), for example). The second is
* when a container #GVariant is created by loading from serialised data
* (with g_variant_new_from_data(), for example).
**/
probe glib.variant_from_buffer = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__from_buffer")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
ref_count = $arg3;
state = $arg4;
}
/**
* probe glib.variant_from_children:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the initial reference count
* @state: the internal state bitfield
*
* Reports that a tree-form #GVariant has been created from a number of
* child elements. This happens in response to the calls like
* g_variant_new_array() and also for g_variant_builder_end().
**/
probe glib.variant_from_children = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__from_children")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
ref_count = $arg3;
state = $arg4;
}
/**
* probe glib.variant_unref:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the reference count before the call
* @state: the internal state bitfield
*
* Reports that g_variant_unref() has been called on a value.
**/
probe glib.variant_unref = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__unref")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
old_ref_count = $arg3;
new_ref_count = old_ref_count - 1;
state = $arg4;
}
/**
* probe glib.variant_ref:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the reference count before the call
* @state: the internal state bitfield
*
* Reports that g_variant_ref() has been called on a value.
**/
probe glib.variant_ref = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__ref")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
old_ref_count = $arg3;
new_ref_count = $arg3 + 1;
state = $arg4;
}
/**
* probe glib.variant_ref_sink:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the reference count before the call
* @state: the internal state bitfield
* @floating: the floating bit of @state
*
* Reports that g_variant_ref_sink() has been called on a value.
**/
probe glib.variant_ref_sink = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__ref_sink")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
ref_count = $arg3;
state = $arg4;
floating = $arg5;
}
/**
* probe glib.variant_take_ref:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the reference count before the call
* @state: the internal state bitfield
* @floating: the floating bit of @state
*
* Reports that g_variant_take_ref() has been called on a value.
**/
probe glib.variant_take_ref = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__take_ref")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
ref_count = $arg3;
state = $arg4;
floating = $arg5;
}
/**
* probe glib.variant_from_parent:
* @value: pointer to #GVariant
* @typeinfo: the raw typeinfo structure pointer
* @typestr: the type string of the #GVariant
* @ref_count: the initial reference count
* @state: the internal state bitfield
*
* Reports that a #GVariant has been created as a result of calling
* g_variant_get_child_value() on a serialised #GVariant (ie:
* deserialisation has occured).
**/
probe glib.variant_from_parent = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("variant__from_parent")
{
value = $arg1;
typeinfo = $arg2;
typestr = gvarianttypeinfo[pid(), typeinfo];
ref_count = $arg3;
state = $arg4;
}

View File

@ -47,4 +47,15 @@ provider glib {
probe rcbox__acquire(void*, unsigned int); probe rcbox__acquire(void*, unsigned int);
probe rcbox__release(void*, unsigned int); probe rcbox__release(void*, unsigned int);
probe rcbox__free(void*); probe rcbox__free(void*);
probe variant__type_info_new(void*, const char*);
probe variant__type_info_free(void*);
probe variant__start_serialise(void*, const char*);
probe variant__end_serialise(void*, const char*);
probe variant__from_buffer(void*, const char*, int, int);
probe variant__from_children(void*, const char*, int, int);
probe variant__unref(void*, const char*, int, int);
probe variant__ref(void*, const char*, int, int);
probe variant__ref_sink(void*, const char*, int, int, int);
probe variant__take_ref(void*, const char*, int, int, int);
probe variant__from_parent(void*, const char*, int, int, void*);
}; };

View File

@ -34,6 +34,7 @@
#include <glib/grefcount.h> #include <glib/grefcount.h>
#include <string.h> #include <string.h>
#include "glib_trace.h"
/* /*
* This file includes the structure definition for GVariant and a small * This file includes the structure definition for GVariant and a small
@ -528,6 +529,7 @@ g_variant_ensure_serialised (GVariant *value)
GBytes *bytes; GBytes *bytes;
gpointer data; gpointer data;
TRACE(GLIB_VARIANT_START_SERIALISE(value, value->type_info));
g_variant_ensure_size (value); g_variant_ensure_size (value);
data = g_malloc (value->size); data = g_malloc (value->size);
g_variant_serialise (value, data); g_variant_serialise (value, data);
@ -540,6 +542,7 @@ g_variant_ensure_serialised (GVariant *value)
value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE; value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE;
value->contents.serialised.checked_offsets_up_to = G_MAXSIZE; value->contents.serialised.checked_offsets_up_to = G_MAXSIZE;
value->state |= STATE_SERIALISED; value->state |= STATE_SERIALISED;
TRACE(GLIB_VARIANT_END_SERIALISE(value, value->type_info));
} }
} }
@ -676,6 +679,8 @@ g_variant_new_from_bytes (const GVariantType *type,
g_clear_pointer (&owned_bytes, g_bytes_unref); g_clear_pointer (&owned_bytes, g_bytes_unref);
TRACE(GLIB_VARIANT_FROM_BUFFER(value, value->type_info, value->ref_count, value->state));
return value; return value;
} }
@ -708,6 +713,7 @@ g_variant_new_from_children (const GVariantType *type,
value = g_variant_alloc (type, FALSE, trusted); value = g_variant_alloc (type, FALSE, trusted);
value->contents.tree.children = children; value->contents.tree.children = children;
value->contents.tree.n_children = n_children; value->contents.tree.n_children = n_children;
TRACE(GLIB_VARIANT_FROM_CHILDREN(value, value->type_info, value->ref_count, value->state));
return value; return value;
} }
@ -781,6 +787,8 @@ g_variant_unref (GVariant *value)
{ {
g_return_if_fail (value != NULL); g_return_if_fail (value != NULL);
TRACE(GLIB_VARIANT_UNREF(value, value->type_info, value->ref_count, value->state));
if (g_atomic_ref_count_dec (&value->ref_count)) if (g_atomic_ref_count_dec (&value->ref_count))
{ {
if G_UNLIKELY (value->state & STATE_LOCKED) if G_UNLIKELY (value->state & STATE_LOCKED)
@ -816,6 +824,8 @@ g_variant_ref (GVariant *value)
{ {
g_return_val_if_fail (value != NULL, NULL); g_return_val_if_fail (value != NULL, NULL);
TRACE(GLIB_VARIANT_REF(value, value->type_info, value->ref_count, value->state));
g_atomic_ref_count_inc (&value->ref_count); g_atomic_ref_count_inc (&value->ref_count);
return value; return value;
@ -860,6 +870,8 @@ g_variant_ref_sink (GVariant *value)
g_variant_lock (value); g_variant_lock (value);
TRACE(GLIB_VARIANT_REF_SINK(value, value->type_info, value->ref_count, value->state, value->state & STATE_FLOATING));
if (~value->state & STATE_FLOATING) if (~value->state & STATE_FLOATING)
g_variant_ref (value); g_variant_ref (value);
else else
@ -915,6 +927,7 @@ g_variant_take_ref (GVariant *value)
g_return_val_if_fail (value != NULL, NULL); g_return_val_if_fail (value != NULL, NULL);
g_return_val_if_fail (!g_atomic_ref_count_compare (&value->ref_count, 0), NULL); g_return_val_if_fail (!g_atomic_ref_count_compare (&value->ref_count, 0), NULL);
TRACE(GLIB_VARIANT_TAKE_REF(value, value->type_info, value->ref_count, value->state, value->state & STATE_FLOATING));
g_atomic_int_and (&value->state, ~STATE_FLOATING); g_atomic_int_and (&value->state, ~STATE_FLOATING);
return value; return value;
@ -1203,6 +1216,8 @@ g_variant_get_child_value (GVariant *value,
child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to; child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to;
child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to; child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to;
TRACE(GLIB_VARIANT_FROM_PARENT(child, child->type_info, child->ref_count, child->state, value));
return child; return child;
} }
} }

View File

@ -30,6 +30,8 @@
#include <glib/ghash.h> #include <glib/ghash.h>
#include <glib/grefcount.h> #include <glib/grefcount.h>
#include "glib_trace.h"
/* < private > /* < private >
* GVariantTypeInfo: * GVariantTypeInfo:
* *
@ -793,6 +795,8 @@ g_variant_type_info_get (const GVariantType *type)
container->type_string = type_string; container->type_string = type_string;
g_atomic_ref_count_init (&container->ref_count); g_atomic_ref_count_init (&container->ref_count);
TRACE(GLIB_VARIANT_TYPE_INFO_NEW(info, container->type_string));
g_hash_table_insert (g_variant_type_info_table, type_string, info); g_hash_table_insert (g_variant_type_info_table, type_string, info);
type_string = NULL; type_string = NULL;
} }
@ -818,6 +822,8 @@ g_variant_type_info_get (const GVariantType *type)
info = g_variant_type_info_basic_table + index; info = g_variant_type_info_basic_table + index;
g_variant_type_info_check (info, 0); g_variant_type_info_check (info, 0);
TRACE(GLIB_VARIANT_TYPE_INFO_NEW(info, g_variant_type_info_basic_chars[index]));
return (GVariantTypeInfo *) info; return (GVariantTypeInfo *) info;
} }
} }
@ -862,6 +868,9 @@ g_variant_type_info_unref (GVariantTypeInfo *info)
g_rec_mutex_lock (&g_variant_type_info_lock); g_rec_mutex_lock (&g_variant_type_info_lock);
if (g_atomic_ref_count_dec (&container->ref_count)) if (g_atomic_ref_count_dec (&container->ref_count))
{ {
TRACE(GLIB_VARIANT_TYPE_INFO_FREE(info));
g_hash_table_remove (g_variant_type_info_table, g_hash_table_remove (g_variant_type_info_table,
container->type_string); container->type_string);
if (g_hash_table_size (g_variant_type_info_table) == 0) if (g_hash_table_size (g_variant_type_info_table) == 0)