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.
/* 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));
}
}
}