2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 inspired by http://swapped.cc/halloc/
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
56 /* use this to force every realloc to change the pointer, to stress test
57 code that might not cope */
58 #define ALWAYS_REALLOC 0
61 #define MAX_TALLOC_SIZE 0x10000000
62 #define TALLOC_MAGIC 0xe814ec70
63 #define TALLOC_FLAG_FREE 0x01
64 #define TALLOC_FLAG_LOOP 0x02
65 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
67 /* by default we abort when given a bad pointer (such as when talloc_free() is called
68 on a pointer that came from malloc() */
70 #define TALLOC_ABORT(reason) abort()
73 #ifndef discard_const_p
74 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
75 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
77 # define discard_const_p(type, ptr) ((type *)(ptr))
81 /* this null_context is only used if talloc_enable_leak_report() or
82 talloc_enable_leak_report_full() is called, otherwise it remains
85 static const void *null_context;
86 static void *cleanup_context;
89 struct talloc_reference_handle {
90 struct talloc_reference_handle *next, *prev;
94 typedef int (*talloc_destructor_t)(void *);
97 struct talloc_chunk *next, *prev;
98 struct talloc_chunk *parent, *child;
99 struct talloc_reference_handle *refs;
101 talloc_destructor_t destructor;
109 /* panic if we get a bad magic value */
110 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
112 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
113 if ((tc->u.flags & ~0xF) != TALLOC_MAGIC) {
114 TALLOC_ABORT("Bad talloc magic value - unknown value");
116 if (tc->u.flags & TALLOC_FLAG_FREE) {
117 TALLOC_ABORT("Bad talloc magic value - double free");
122 /* hook into the front of the list */
123 #define _TLIST_ADD(list, p) \
127 (p)->next = (p)->prev = NULL; \
129 (list)->prev = (p); \
130 (p)->next = (list); \
136 /* remove an element from a list - element doesn't have to be in list. */
137 #define _TLIST_REMOVE(list, p) \
139 if ((p) == (list)) { \
140 (list) = (p)->next; \
141 if (list) (list)->prev = NULL; \
143 if ((p)->prev) (p)->prev->next = (p)->next; \
144 if ((p)->next) (p)->next->prev = (p)->prev; \
146 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
151 return the parent chunk of a pointer
153 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
155 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
156 while (tc->prev) tc=tc->prev;
160 void *talloc_parent(const void *ptr)
162 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
163 return (void *)(tc+1);
167 Allocate a bit of memory as a child of an existing pointer
169 void *_talloc(const void *context, size_t size)
171 struct talloc_chunk *tc;
173 if (context == NULL) {
174 context = null_context;
177 if (size >= MAX_TALLOC_SIZE) {
181 tc = malloc(sizeof(*tc)+size);
182 if (tc == NULL) return NULL;
185 tc->u.flags = TALLOC_MAGIC;
186 tc->destructor = NULL;
192 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
197 parent->child->parent = NULL;
200 _TLIST_ADD(parent->child, tc);
202 tc->next = tc->prev = tc->parent = NULL;
205 return (void *)(tc+1);
210 setup a destructor to be called on free of a pointer
211 the destructor should return 0 on success, or -1 on failure.
212 if the destructor fails then the free is failed, and the memory can
213 be continued to be used
215 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
217 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
218 tc->destructor = destructor;
222 increase the reference count on a piece of memory.
224 void talloc_increase_ref_count(const void *ptr)
226 talloc_reference(null_context, ptr);
230 helper for talloc_reference()
232 static int talloc_reference_destructor(void *ptr)
234 struct talloc_reference_handle *handle = ptr;
235 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
236 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
237 if (tc1->destructor != (talloc_destructor_t)-1) {
238 tc1->destructor = NULL;
240 _TLIST_REMOVE(tc2->refs, handle);
246 make a secondary reference to a pointer, hanging off the given context.
247 the pointer remains valid until both the original caller and this given
250 the major use for this is when two different structures need to reference the
251 same underlying data, and you want to be able to free the two instances separately,
254 void *talloc_reference(const void *context, const void *ptr)
256 struct talloc_chunk *tc;
257 struct talloc_reference_handle *handle;
258 if (ptr == NULL) return NULL;
260 tc = talloc_chunk_from_ptr(ptr);
261 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
263 if (handle == NULL) return NULL;
265 /* note that we hang the destructor off the handle, not the
266 main context as that allows the caller to still setup their
267 own destructor on the context if they want to */
268 talloc_set_destructor(handle, talloc_reference_destructor);
269 handle->ptr = discard_const_p(void, ptr);
270 _TLIST_ADD(tc->refs, handle);
275 remove a secondary reference to a pointer. This undo's what
276 talloc_reference() has done. The context and pointer arguments
277 must match those given to a talloc_reference()
279 static int talloc_unreference(const void *context, const void *ptr)
281 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
282 struct talloc_reference_handle *h;
284 if (context == NULL) {
285 context = null_context;
288 for (h=tc->refs;h;h=h->next) {
289 struct talloc_chunk *p = talloc_parent_chunk(h);
290 if ((p==NULL && context==NULL) || p+1 == context) break;
296 talloc_set_destructor(h, NULL);
297 _TLIST_REMOVE(tc->refs, h);
303 remove a specific parent context from a pointer. This is a more
304 controlled varient of talloc_free()
306 int talloc_unlink(const void *context, void *ptr)
308 struct talloc_chunk *tc_p, *new_p;
315 if (context == NULL) {
316 context = null_context;
319 if (talloc_unreference(context, ptr) == 0) {
323 if (context == NULL) {
324 if (talloc_parent_chunk(ptr) != NULL) {
328 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
333 tc_p = talloc_chunk_from_ptr(ptr);
335 if (tc_p->refs == NULL) {
336 return talloc_free(ptr);
339 new_p = talloc_parent_chunk(tc_p->refs);
341 new_parent = new_p+1;
346 if (talloc_unreference(new_parent, ptr) != 0) {
350 talloc_steal(new_parent, ptr);
356 add a name to an existing pointer - va_list version
358 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
360 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
362 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
363 tc->name = talloc_vasprintf(ptr, fmt, ap);
365 talloc_set_name_const(tc->name, ".name");
370 add a name to an existing pointer
372 void talloc_set_name(const void *ptr, const char *fmt, ...)
376 talloc_set_name_v(ptr, fmt, ap);
381 more efficient way to add a name to a pointer - the name must point to a
384 void talloc_set_name_const(const void *ptr, const char *name)
386 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
391 create a named talloc pointer. Any talloc pointer can be named, and
392 talloc_named() operates just like talloc() except that it allows you
395 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
400 ptr = _talloc(context, size);
401 if (ptr == NULL) return NULL;
404 talloc_set_name_v(ptr, fmt, ap);
411 create a named talloc pointer. Any talloc pointer can be named, and
412 talloc_named() operates just like talloc() except that it allows you
415 void *talloc_named_const(const void *context, size_t size, const char *name)
419 ptr = _talloc(context, size);
424 talloc_set_name_const(ptr, name);
430 return the name of a talloc ptr, or "UNNAMED"
432 const char *talloc_get_name(const void *ptr)
434 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
435 if (tc->name == TALLOC_MAGIC_REFERENCE) {
446 check if a pointer has the given name. If it does, return the pointer,
447 otherwise return NULL
449 void *talloc_check_name(const void *ptr, const char *name)
452 if (ptr == NULL) return NULL;
453 pname = talloc_get_name(ptr);
454 if (pname == name || strcmp(pname, name) == 0) {
455 return discard_const_p(void, ptr);
462 this is for compatibility with older versions of talloc
464 void *talloc_init(const char *fmt, ...)
469 ptr = _talloc(NULL, 0);
470 if (ptr == NULL) return NULL;
473 talloc_set_name_v(ptr, fmt, ap);
480 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
481 should probably not be used in new code. It's in here to keep the talloc
482 code consistent across Samba 3 and 4.
484 void talloc_free_children(void *ptr)
486 struct talloc_chunk *tc;
492 tc = talloc_chunk_from_ptr(ptr);
495 /* we need to work out who will own an abandoned child
496 if it cannot be freed. In priority order, the first
497 choice is owner of any remaining reference to this
498 pointer, the second choice is our parent, and the
499 final choice is the null context. */
500 void *child = tc->child+1;
501 const void *new_parent = null_context;
502 if (tc->child->refs) {
503 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
504 if (p) new_parent = p+1;
506 if (talloc_free(child) == -1) {
507 if (new_parent == null_context) {
508 struct talloc_chunk *p = talloc_parent_chunk(ptr);
509 if (p) new_parent = p+1;
511 talloc_steal(new_parent, child);
517 free a talloc pointer. This also frees all child pointers of this
520 return 0 if the memory is actually freed, otherwise -1. The memory
521 will not be freed if the ref_count is > 1 or the destructor (if
522 any) returns non-zero
524 int talloc_free(void *ptr)
526 struct talloc_chunk *tc;
532 tc = talloc_chunk_from_ptr(ptr);
535 talloc_reference_destructor(tc->refs);
539 if (tc->u.flags & TALLOC_FLAG_LOOP) {
540 /* we have a free loop - stop looping */
544 if (tc->destructor) {
545 talloc_destructor_t d = tc->destructor;
546 if (d == (talloc_destructor_t)-1) {
549 tc->destructor = (talloc_destructor_t)-1;
554 tc->destructor = NULL;
557 tc->u.flags |= TALLOC_FLAG_LOOP;
559 talloc_free_children(ptr);
562 _TLIST_REMOVE(tc->parent->child, tc);
563 if (tc->parent->child) {
564 tc->parent->child->parent = tc->parent;
567 if (tc->prev) tc->prev->next = tc->next;
568 if (tc->next) tc->next->prev = tc->prev;
571 tc->u.flags |= TALLOC_FLAG_FREE;
580 A talloc version of realloc. The context argument is only used if
583 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
585 struct talloc_chunk *tc;
588 /* size zero is equivalent to free() */
594 if (size >= MAX_TALLOC_SIZE) {
598 /* realloc(NULL) is equavalent to malloc() */
600 return talloc_named_const(context, size, name);
603 tc = talloc_chunk_from_ptr(ptr);
605 /* don't allow realloc on referenced pointers */
610 /* by resetting magic we catch users of the old memory */
611 tc->u.flags |= TALLOC_FLAG_FREE;
614 new_ptr = malloc(size + sizeof(*tc));
616 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
620 new_ptr = realloc(tc, size + sizeof(*tc));
623 tc->u.flags &= ~TALLOC_FLAG_FREE;
628 tc->u.flags &= ~TALLOC_FLAG_FREE;
630 tc->parent->child = new_ptr;
633 tc->child->parent = new_ptr;
644 talloc_set_name_const(tc+1, name);
646 return (void *)(tc+1);
650 move a lump of memory from one talloc context to another return the
651 ptr on success, or NULL if it could not be transferred.
652 passing NULL as ptr will always return NULL with no side effects.
654 void *talloc_steal(const void *new_ctx, const void *ptr)
656 struct talloc_chunk *tc, *new_tc;
662 if (new_ctx == NULL) {
663 new_ctx = null_context;
666 tc = talloc_chunk_from_ptr(ptr);
668 if (new_ctx == NULL) {
670 _TLIST_REMOVE(tc->parent->child, tc);
671 if (tc->parent->child) {
672 tc->parent->child->parent = tc->parent;
675 if (tc->prev) tc->prev->next = tc->next;
676 if (tc->next) tc->next->prev = tc->prev;
679 tc->parent = tc->next = tc->prev = NULL;
680 return discard_const_p(void, ptr);
683 new_tc = talloc_chunk_from_ptr(new_ctx);
686 return discard_const_p(void, ptr);
690 _TLIST_REMOVE(tc->parent->child, tc);
691 if (tc->parent->child) {
692 tc->parent->child->parent = tc->parent;
695 if (tc->prev) tc->prev->next = tc->next;
696 if (tc->next) tc->next->prev = tc->prev;
700 if (new_tc->child) new_tc->child->parent = NULL;
701 _TLIST_ADD(new_tc->child, tc);
703 return discard_const_p(void, ptr);
707 return the total size of a talloc pool (subtree)
709 off_t talloc_total_size(const void *ptr)
712 struct talloc_chunk *c, *tc;
721 tc = talloc_chunk_from_ptr(ptr);
723 if (tc->u.flags & TALLOC_FLAG_LOOP) {
727 tc->u.flags |= TALLOC_FLAG_LOOP;
730 for (c=tc->child;c;c=c->next) {
731 total += talloc_total_size(c+1);
734 tc->u.flags &= ~TALLOC_FLAG_LOOP;
740 return the total number of blocks in a talloc pool (subtree)
742 off_t talloc_total_blocks(const void *ptr)
745 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
747 if (tc->u.flags & TALLOC_FLAG_LOOP) {
751 tc->u.flags |= TALLOC_FLAG_LOOP;
754 for (c=tc->child;c;c=c->next) {
755 total += talloc_total_blocks(c+1);
758 tc->u.flags &= ~TALLOC_FLAG_LOOP;
764 return the number of external references to a pointer
766 static int talloc_reference_count(const void *ptr)
768 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
769 struct talloc_reference_handle *h;
772 for (h=tc->refs;h;h=h->next) {
779 report on memory usage by all children of a pointer, giving a full tree view
781 void talloc_report_depth(const void *ptr, FILE *f, int depth)
783 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
785 if (tc->u.flags & TALLOC_FLAG_LOOP) {
789 tc->u.flags |= TALLOC_FLAG_LOOP;
791 for (c=tc->child;c;c=c->next) {
792 if (c->name == TALLOC_MAGIC_REFERENCE) {
793 struct talloc_reference_handle *handle = (void *)(c+1);
794 const char *name2 = talloc_get_name(handle->ptr);
795 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
797 const char *name = talloc_get_name(c+1);
798 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
801 (unsigned long)talloc_total_size(c+1),
802 (unsigned long)talloc_total_blocks(c+1),
803 talloc_reference_count(c+1));
804 talloc_report_depth(c+1, f, depth+1);
807 tc->u.flags &= ~TALLOC_FLAG_LOOP;
811 report on memory usage by all children of a pointer, giving a full tree view
813 void talloc_report_full(const void *ptr, FILE *f)
818 if (ptr == NULL) return;
820 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
821 talloc_get_name(ptr),
822 (unsigned long)talloc_total_size(ptr),
823 (unsigned long)talloc_total_blocks(ptr));
825 talloc_report_depth(ptr, f, 1);
830 report on memory usage by all children of a pointer
832 void talloc_report(const void *ptr, FILE *f)
834 struct talloc_chunk *c, *tc;
839 if (ptr == NULL) return;
841 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
842 talloc_get_name(ptr),
843 (unsigned long)talloc_total_size(ptr),
844 (unsigned long)talloc_total_blocks(ptr));
846 tc = talloc_chunk_from_ptr(ptr);
848 for (c=tc->child;c;c=c->next) {
849 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
850 talloc_get_name(c+1),
851 (unsigned long)talloc_total_size(c+1),
852 (unsigned long)talloc_total_blocks(c+1));
858 report on any memory hanging off the null context
860 static void talloc_report_null(void)
862 if (talloc_total_size(null_context) != 0) {
863 talloc_report(null_context, stderr);
868 report on any memory hanging off the null context
870 static void talloc_report_null_full(void)
872 if (talloc_total_size(null_context) != 0) {
873 talloc_report_full(null_context, stderr);
878 enable tracking of the NULL context
880 void talloc_enable_null_tracking(void)
882 if (null_context == NULL) {
883 null_context = talloc_named_const(NULL, 0, "null_context");
888 enable leak reporting on exit
890 void talloc_enable_leak_report(void)
892 talloc_enable_null_tracking();
893 atexit(talloc_report_null);
897 enable full leak reporting on exit
899 void talloc_enable_leak_report_full(void)
901 talloc_enable_null_tracking();
902 atexit(talloc_report_null_full);
906 talloc and zero memory.
908 void *_talloc_zero(const void *ctx, size_t size, const char *name)
910 void *p = talloc_named_const(ctx, size, name);
913 memset(p, '\0', size);
921 memdup with a talloc.
923 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
925 void *newp = talloc_named_const(t, size, name);
928 memcpy(newp, p, size);
937 char *talloc_strdup(const void *t, const char *p)
943 ret = talloc_memdup(t, p, strlen(p) + 1);
945 talloc_set_name_const(ret, ret);
951 append to a talloced string
953 char *talloc_append_string(const void *t, char *orig, const char *append)
956 size_t olen = strlen(orig);
957 size_t alenz = strlen(append) + 1;
962 ret = talloc_realloc(t, orig, char, olen + alenz);
966 /* append the string with the trailing \0 */
967 memcpy(&ret[olen], append, alenz);
973 strndup with a talloc
975 char *talloc_strndup(const void *t, const char *p, size_t n)
980 for (len=0; len<n && p[len]; len++) ;
982 ret = _talloc(t, len + 1);
983 if (!ret) { return NULL; }
986 talloc_set_name_const(ret, ret);
992 #define VA_COPY(dest, src) va_copy(dest, src)
993 #elif defined(HAVE___VA_COPY)
994 #define VA_COPY(dest, src) __va_copy(dest, src)
996 #define VA_COPY(dest, src) (dest) = (src)
1000 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1008 len = vsnprintf(NULL, 0, fmt, ap2);
1010 ret = _talloc(t, len+1);
1013 vsnprintf(ret, len+1, fmt, ap2);
1014 talloc_set_name_const(ret, ret);
1022 Perform string formatting, and return a pointer to newly allocated
1023 memory holding the result, inside a memory pool.
1025 char *talloc_asprintf(const void *t, const char *fmt, ...)
1031 ret = talloc_vasprintf(t, fmt, ap);
1038 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1039 * and return @p s, which may have moved. Good for gradually
1040 * accumulating output into a string buffer.
1043 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1045 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1047 struct talloc_chunk *tc;
1052 return talloc_vasprintf(NULL, fmt, ap);
1055 tc = talloc_chunk_from_ptr(s);
1059 s_len = tc->size - 1;
1060 len = vsnprintf(NULL, 0, fmt, ap2);
1062 s = talloc_realloc(NULL, s, char, s_len + len+1);
1063 if (!s) return NULL;
1067 vsnprintf(s+s_len, len+1, fmt, ap2);
1068 talloc_set_name_const(s, s);
1074 Realloc @p s to append the formatted result of @p fmt and return @p
1075 s, which may have moved. Good for gradually accumulating output
1076 into a string buffer.
1078 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1083 s = talloc_vasprintf_append(s, fmt, ap);
1089 alloc an array, checking for integer overflow in the array size
1091 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1093 if (count >= MAX_TALLOC_SIZE/el_size) {
1096 return talloc_named_const(ctx, el_size * count, name);
1100 alloc an zero array, checking for integer overflow in the array size
1102 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1104 if (count >= MAX_TALLOC_SIZE/el_size) {
1107 return _talloc_zero(ctx, el_size * count, name);
1112 realloc an array, checking for integer overflow in the array size
1114 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1116 if (count >= MAX_TALLOC_SIZE/el_size) {
1119 return _talloc_realloc(ctx, ptr, el_size * count, name);
1123 a function version of talloc_realloc(), so it can be passed as a function pointer
1124 to libraries that want a realloc function (a realloc function encapsulates
1125 all the basic capabilities of an allocation library, which is why this is useful)
1127 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1129 return _talloc_realloc(context, ptr, size, NULL);
1133 static void talloc_autofree(void)
1135 talloc_free(cleanup_context);
1136 cleanup_context = NULL;
1140 return a context which will be auto-freed on exit
1141 this is useful for reducing the noise in leak reports
1143 void *talloc_autofree_context(void)
1145 if (cleanup_context == NULL) {
1146 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1147 atexit(talloc_autofree);
1149 return cleanup_context;
1152 size_t talloc_get_size(const void *context)
1154 struct talloc_chunk *tc;
1156 if (context == NULL)
1159 tc = talloc_chunk_from_ptr(context);
1165 find a parent of this context that has the given name, if any
1167 void *talloc_find_parent_byname(const void *context, const char *name)
1169 struct talloc_chunk *tc;
1171 if (context == NULL) {
1175 tc = talloc_chunk_from_ptr(context);
1177 if (tc->name && strcmp(tc->name, name) == 0) {
1178 return (void*)(tc+1);
1180 while (tc && tc->prev) tc = tc->prev;
1187 show the parentage of a context
1189 void talloc_show_parents(const void *context, FILE *file)
1191 struct talloc_chunk *tc;
1193 if (context == NULL) {
1194 fprintf(file, "talloc no parents for NULL\n");
1198 tc = talloc_chunk_from_ptr(context);
1199 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1201 fprintf(file, "\t'%s'\n", talloc_get_name(tc+1));
1202 while (tc && tc->prev) tc = tc->prev;