(throwaway) Extra debug stuff for finding what's stolen.
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 29 Jun 2012 05:46:40 +0000 (15:16 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 29 Jun 2012 05:46:40 +0000 (15:16 +0930)
lib/talloc/talloc.c

index 434143aad0286e7b0784908493c4f7b7f5fd6051..ebaf953b6eed84f260736160b0e988aa6a82bfee 100644 (file)
@@ -943,6 +943,35 @@ static inline int _talloc_free_internal(void *ptr, const char *location)
        return 0;
 }
 
+static char *talloc_dump_chain(const char *msg, const void *ptr)
+{
+       struct talloc_chunk *tc;
+       char *text = talloc_strdup(NULL, msg);
+
+       if (ptr == NULL) {
+               return text;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+       while (tc) {
+               text = talloc_asprintf_append(text, "  %p (%s)", TC_PTR_FROM_CHUNK(tc),
+                          talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
+               if (tc->flags & TALLOC_FLAG_POOL) {
+                       text = talloc_asprintf_append(text, " (POOL)");
+               } else if (tc->pool) {
+                       text = talloc_asprintf_append(text, " (in pool %p %s)",
+                                  TC_PTR_FROM_CHUNK(tc->pool),
+                                  talloc_get_name(TC_PTR_FROM_CHUNK(tc->pool)));
+               }
+               text = talloc_asprintf_append(text, "\n");
+               while (tc && tc->prev) tc = tc->prev;
+               if (tc) {
+                       tc = tc->parent;
+               }
+       }
+       return text;
+}
+
 /* 
    move a lump of memory from one talloc context to another return the
    ptr on success, or NULL if it could not be transferred.
@@ -978,17 +1007,27 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
                /* They can only steal into the same pool without risking
                 * the pool being stuck waiting. */
                if (new_pool != tc->pool) {
-                       /* Last chance!  If new pool is a child of the old pool,
-                        * that's OK too: we'll still have to free this first. */
-                       if (!new_pool ||
+                       /* If new parent is a child of the same pool,
+                        * that's OK too: we'd still have to free this
+                        * parent before we free the pool. */
+                       if (!new_ctx ||
                            !talloc_is_parent(TC_PTR_FROM_CHUNK(tc->pool),
-                                             TC_PTR_FROM_CHUNK(new_pool))) {
+                                             TC_PTR_FROM_CHUNK(new_ctx))) {
                                talloc_log("WARNING: talloc_steal %p (%s)"
-                                          " from pool %p (%s)\n", ptr,
-                                          talloc_get_name(ptr),
+                                          " from pool %p (%s)"
+                                          " to %p (pool %s)\n%s\n%s\n",
+                                          ptr, talloc_get_name(ptr),
                                           TC_PTR_FROM_CHUNK(tc->pool),
                                           talloc_get_name(TC_PTR_FROM_CHUNK(
-                                                                  tc->pool)));
+                                                                  tc->pool)),
+                                          new_ctx,
+                                          new_pool ? talloc_get_name(
+                                                  TC_PTR_FROM_CHUNK(new_pool))
+                                          : "null",
+                                          talloc_dump_chain("pointer we're stealing:\n",
+                                                            ptr),
+                                          talloc_dump_chain("context we're stealing onto:\n",
+                                                            new_ctx));
                        }
                }
        }