Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hook more g_object_new_xxx function to prevent missing some GObjects tracking #6

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 74 additions & 37 deletions gobject-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,59 +328,96 @@ _object_finalized (gpointer data,
G_UNLOCK (gobject_list);
}

static void
_track_object(GObject* obj)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As evil as it sounds... I would consider making this a macro so that it doesn't turn up into your tracebacks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is wrong with this showing in the traces? I would prefer an inline function over a macro if that also solves the problem.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a frame that's not useful in your trace. Inline works too. My C is rusty, I forgot inline was a thing :-P

{
const char* obj_name = G_OBJECT_TYPE_NAME (obj);

G_LOCK (gobject_list);

if (g_hash_table_lookup (gobject_list_state.objects, obj) == NULL &&
object_filter (obj_name))
{
if (display_filter (DISPLAY_FLAG_CREATE))
{
g_print (" ++ Created object %p, %s\n", obj, obj_name);
print_trace();
}

/* FIXME: For thread safety, GWeakRef should be used here, except it
* won’t give us notify callbacks. Perhaps an opportunistic combination
* of GWeakRef and g_object_weak_ref() — the former for safety, the latter
* for notifications (with the knowledge that due to races, some
* notifications may get omitted)?
*
* Alternatively, we could abuse GToggleRef. Inadvisable because other
* code could be using it.
*
* Alternatively, we could switch to a garbage-collection style of
* working, where gobject-list runs in its own thread and uses GWeakRefs
* to keep track of objects. Periodically, it would check the hash table
* and notify of which references have been nullified. */
g_object_weak_ref (obj, _object_finalized, NULL);

g_hash_table_insert (gobject_list_state.objects, obj,
GUINT_TO_POINTER (TRUE));
g_hash_table_insert (gobject_list_state.added, obj,
GUINT_TO_POINTER (TRUE));
}

G_UNLOCK (gobject_list);
}

GObject*
g_object_new_valist (GType type,
const gchar *first,
va_list var_args)
{

gpointer (*real_g_object_new_valist) (GType, const char *, va_list);
GObject *obj;

real_g_object_new_valist = get_func ("g_object_new_valist");

obj = (GObject*)real_g_object_new_valist (type, first, var_args);

_track_object(obj);
return obj;
}

gpointer
g_object_new (GType type,
const char *first,
...)
{
gpointer (* real_g_object_new_valist) (GType, const char *, va_list);

gpointer (*real_g_object_new_valist) (GType, const char *, va_list);
va_list var_args;
GObject *obj;
const char *obj_name;

real_g_object_new_valist = get_func ("g_object_new_valist");

va_start (var_args, first);
obj = real_g_object_new_valist (type, first, var_args);
obj = (GObject*)real_g_object_new_valist (type, first, var_args);
va_end (var_args);

obj_name = G_OBJECT_TYPE_NAME (obj);

G_LOCK (gobject_list);

if (g_hash_table_lookup (gobject_list_state.objects, obj) == NULL &&
object_filter (obj_name))
{
if (display_filter (DISPLAY_FLAG_CREATE))
{
g_print (" ++ Created object %p, %s\n", obj, obj_name);
print_trace();
}
_track_object(obj);
return obj;
}

/* FIXME: For thread safety, GWeakRef should be used here, except it
* won’t give us notify callbacks. Perhaps an opportunistic combination
* of GWeakRef and g_object_weak_ref() — the former for safety, the latter
* for notifications (with the knowledge that due to races, some
* notifications may get omitted)?
*
* Alternatively, we could abuse GToggleRef. Inadvisable because other
* code could be using it.
*
* Alternatively, we could switch to a garbage-collection style of
* working, where gobject-list runs in its own thread and uses GWeakRefs
* to keep track of objects. Periodically, it would check the hash table
* and notify of which references have been nullified. */
g_object_weak_ref (obj, _object_finalized, NULL);

g_hash_table_insert (gobject_list_state.objects, obj,
GUINT_TO_POINTER (TRUE));
g_hash_table_insert (gobject_list_state.added, obj,
GUINT_TO_POINTER (TRUE));
}
gpointer
g_object_newv (GType object_type,
guint n_parameters,
GParameter *parameters)
{
GObject *obj;
gpointer (*real_g_object_newv )(GType object_type, guint n_parameters,GParameter *parameters);

G_UNLOCK (gobject_list);
real_g_object_newv = get_func ("g_object_newv");

return obj;
obj = (GObject*)real_g_object_newv(object_type,n_parameters,parameters);
_track_object(obj);
return obj;
}

gpointer
Expand Down