[gjs/wip/gdbus-2: 2/13] Keep Alive: add a debugging method to print all active roots



commit 83a6e435711091b98990c311cd8c1d55bcc834cb
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Wed Jul 4 22:32:03 2012 +0200

    Keep Alive: add a debugging method to print all active roots
    
    Adds a print_roots() to keep-alive objects (such as
    __gc_this_on_context_destroy, where GObjects are stored), which
    prints a dump of all objects known to it on stderr.
    This is primarily meant to debug GObject cycles and leaks that
    are not detected.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679688

 gi/keep-alive.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 70 insertions(+), 1 deletions(-)
---
diff --git a/gi/keep-alive.c b/gi/keep-alive.c
index d45740a..afacf14 100644
--- a/gi/keep-alive.c
+++ b/gi/keep-alive.c
@@ -165,6 +165,74 @@ keep_alive_trace(JSTracer *tracer,
     priv->inside_trace = FALSE;
 }
 
+static char*
+jsobj_to_string(JSContext* cx, JSObject *obj)
+{
+    char* value = NULL;
+
+    if (JS_ObjectIsFunction(cx, obj)) {
+        JSFunction *fn = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(obj));
+        JSString *str;
+
+        str = JS_GetFunctionId(fn);
+        if (str) {
+            value = NULL;
+            gjs_try_string_to_utf8(cx, STRING_TO_JSVAL(str), &value, NULL);
+        } else {
+            value = g_strdup ("anonymous function");
+        }
+    } else {
+	value = g_strdup_printf("[object %s]", JS_GetClass(cx, obj)->name);
+    }
+
+    if (!value)
+        value = g_strdup ("[unknown object]");
+    return value;
+}
+
+static void
+print_foreach(void *key,
+              void *value,
+              void *data)
+{
+    Child *child = value;
+    JSContext *context = data;
+
+    if (child->child != NULL) {
+        char *string;
+
+        string = jsobj_to_string(context, child->child);
+        g_printerr("%p: %s\n", child->child, string);
+
+        g_free(string);
+    }
+}
+
+static JSBool
+print_roots (JSContext *context,
+             uintN      argc,
+             jsval     *vp)
+{
+    JSObject *obj = JS_THIS_OBJECT(context, vp);
+    KeepAlive *priv;
+
+    JS_BeginRequest(context);
+
+    priv = priv_from_js(context, obj);
+
+    if (priv == NULL) /* prototype */
+        return JS_TRUE;
+
+    g_printerr("**** BEGIN GJS root table dump ****\n");
+    g_hash_table_foreach(priv->children, print_foreach, context);
+    g_printerr("**** END GJS root table dump ****\n");
+
+    JS_SET_RVAL(context, vp, JSVAL_VOID);
+    JS_EndRequest(context);
+
+    return JS_TRUE;
+}
+
 /* The bizarre thing about this vtable is that it applies to both
  * instances of the object, and to the prototype that instances of the
  * class have.
@@ -201,7 +269,8 @@ static JSPropertySpec gjs_keep_alive_proto_props[] = {
 };
 
 static JSFunctionSpec gjs_keep_alive_proto_funcs[] = {
-    { NULL }
+    { "print_roots", (JSNative)print_roots, 0, 0 },
+    { NULL },
 };
 
 JSObject*



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]