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
9 Copyright (C) Stefan Metzmacher 2006
11 ** NOTE! The following LGPL license applies to the talloc
12 ** library. This does NOT imply that all of Samba is released
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 inspired by http://swapped.cc/halloc/
38 #include <sys/types.h>
41 /* use this to force every realloc to change the pointer, to stress test
42 code that might not cope */
43 #define ALWAYS_REALLOC 0
46 #define MAX_TALLOC_SIZE 0x7FFFFFFF
47 #define TALLOC_MAGIC 0xe814ec70
48 #define TALLOC_FLAG_FREE 0x01
49 #define TALLOC_FLAG_LOOP 0x02
50 #define TALLOC_FLAG_EXT_ALLOC 0x04
51 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
53 /* by default we abort when given a bad pointer (such as when talloc_free() is called
54 on a pointer that came from malloc() */
56 #define TALLOC_ABORT(reason) abort()
59 #ifndef discard_const_p
60 #if defined(INTPTR_MIN)
61 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
63 # define discard_const_p(type, ptr) ((type *)(ptr))
67 /* these macros gain us a few percent of speed on gcc */
68 #if HAVE_BUILTIN_EXPECT
69 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
70 as its first argument */
71 #define likely(x) __builtin_expect(!!(x), 1)
72 #define unlikely(x) __builtin_expect(!!(x), 0)
78 /* this null_context is only used if talloc_enable_leak_report() or
79 talloc_enable_leak_report_full() is called, otherwise it remains
82 static void *null_context;
83 static pid_t *autofree_context;
85 static void *(*tc_external_realloc)(const void *parent, void *ptr, size_t size);
86 static void (*tc_lock)(const void *ctx);
87 static void (*tc_unlock)(void);
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;
100 talloc_destructor_t destructor;
106 /* 16 byte alignment seems to keep everyone happy */
107 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
108 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
110 /* panic if we get a bad magic value */
111 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
113 const char *pp = (const char *)ptr;
114 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
115 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
116 if (tc->flags & TALLOC_FLAG_FREE) {
117 TALLOC_ABORT("Bad talloc magic value - double free");
119 TALLOC_ABORT("Bad talloc magic value - unknown value");
125 /* hook into the front of the list */
126 #define _TLIST_ADD(list, p) \
130 (p)->next = (p)->prev = NULL; \
132 (list)->prev = (p); \
133 (p)->next = (list); \
139 /* remove an element from a list - element doesn't have to be in list. */
140 #define _TLIST_REMOVE(list, p) \
142 if ((p) == (list)) { \
143 (list) = (p)->next; \
144 if (list) (list)->prev = NULL; \
146 if ((p)->prev) (p)->prev->next = (p)->next; \
147 if ((p)->next) (p)->next->prev = (p)->prev; \
149 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
153 static inline void lock(const void *p)
156 struct talloc_chunk *tc = talloc_chunk_from_ptr(p);
158 if (tc->flags & TALLOC_FLAG_EXT_ALLOC) {
160 TALLOC_ABORT("nested locking");
167 static inline void unlock(void)
176 return the parent chunk of a pointer
178 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
180 struct talloc_chunk *tc;
182 if (unlikely(ptr == NULL)) {
186 tc = talloc_chunk_from_ptr(ptr);
187 while (tc->prev) tc=tc->prev;
192 /* This version doesn't do locking, so you must already have it. */
193 static void *talloc_parent_nolock(const void *ptr)
195 struct talloc_chunk *tc;
197 tc = talloc_parent_chunk(ptr);
198 return tc ? TC_PTR_FROM_CHUNK(tc) : NULL;
201 void *talloc_parent(const void *ptr)
206 parent = talloc_parent_nolock(ptr);
214 const char *talloc_parent_name(const void *ptr)
216 struct talloc_chunk *tc;
219 tc = talloc_parent_chunk(ptr);
222 return tc? tc->name : NULL;
225 static void *init_talloc(struct talloc_chunk *parent,
226 struct talloc_chunk *tc,
227 size_t size, int external)
229 if (unlikely(tc == NULL))
233 tc->flags = TALLOC_MAGIC;
235 tc->flags |= TALLOC_FLAG_EXT_ALLOC;
236 tc->destructor = NULL;
241 if (likely(parent)) {
243 parent->child->parent = NULL;
244 tc->next = parent->child;
253 tc->next = tc->prev = tc->parent = NULL;
256 return TC_PTR_FROM_CHUNK(tc);
260 Allocate a bit of memory as a child of an existing pointer
262 static inline void *__talloc(const void *context, size_t size)
264 struct talloc_chunk *tc;
265 struct talloc_chunk *parent = NULL;
268 if (unlikely(context == NULL)) {
269 context = null_context;
272 if (unlikely(size >= MAX_TALLOC_SIZE)) {
276 if (likely(context)) {
277 parent = talloc_chunk_from_ptr(context);
278 if (unlikely(parent->flags & TALLOC_FLAG_EXT_ALLOC)) {
279 tc = tc_external_realloc(context, NULL,
286 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
288 return init_talloc(parent, tc, size, external);
292 setup a destructor to be called on free of a pointer
293 the destructor should return 0 on success, or -1 on failure.
294 if the destructor fails then the free is failed, and the memory can
295 be continued to be used
297 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
299 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
300 tc->destructor = destructor;
304 increase the reference count on a piece of memory.
306 int talloc_increase_ref_count(const void *ptr)
308 if (unlikely(!talloc_reference(null_context, ptr))) {
315 helper for talloc_reference()
317 this is referenced by a function pointer and should not be inline
319 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
321 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
322 _TLIST_REMOVE(ptr_tc->refs, handle);
327 more efficient way to add a name to a pointer - the name must point to a
330 static inline void _talloc_set_name_const(const void *ptr, const char *name)
332 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
337 internal talloc_named_const()
339 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
343 ptr = __talloc(context, size);
344 if (unlikely(ptr == NULL)) {
348 _talloc_set_name_const(ptr, name);
354 make a secondary reference to a pointer, hanging off the given context.
355 the pointer remains valid until both the original caller and this given
358 the major use for this is when two different structures need to reference the
359 same underlying data, and you want to be able to free the two instances separately,
362 void *_talloc_reference(const void *context, const void *ptr)
364 struct talloc_chunk *tc;
365 struct talloc_reference_handle *handle;
366 if (unlikely(ptr == NULL)) return NULL;
369 tc = talloc_chunk_from_ptr(ptr);
370 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
371 sizeof(struct talloc_reference_handle),
372 TALLOC_MAGIC_REFERENCE);
373 if (unlikely(handle == NULL)) {
378 /* note that we hang the destructor off the handle, not the
379 main context as that allows the caller to still setup their
380 own destructor on the context if they want to */
381 talloc_set_destructor(handle, talloc_reference_destructor);
382 handle->ptr = discard_const_p(void, ptr);
383 _TLIST_ADD(tc->refs, handle);
389 return 1 if ptr is a parent of context
391 static int _talloc_is_parent(const void *context, const void *ptr)
393 struct talloc_chunk *tc;
395 if (context == NULL) {
399 tc = talloc_chunk_from_ptr(context);
401 if (TC_PTR_FROM_CHUNK(tc) == ptr) {
404 while (tc && tc->prev) tc = tc->prev;
413 move a lump of memory from one talloc context to another return the
414 ptr on success, or NULL if it could not be transferred.
415 passing NULL as ptr will always return NULL with no side effects.
417 static void *__talloc_steal(const void *new_ctx, const void *ptr)
419 struct talloc_chunk *tc, *new_tc;
421 if (unlikely(!ptr)) {
425 if (unlikely(new_ctx == NULL)) {
426 new_ctx = null_context;
429 tc = talloc_chunk_from_ptr(ptr);
431 if (unlikely(new_ctx == NULL)) {
433 _TLIST_REMOVE(tc->parent->child, tc);
434 if (tc->parent->child) {
435 tc->parent->child->parent = tc->parent;
438 if (tc->prev) tc->prev->next = tc->next;
439 if (tc->next) tc->next->prev = tc->prev;
442 tc->parent = tc->next = tc->prev = NULL;
443 return discard_const_p(void, ptr);
446 new_tc = talloc_chunk_from_ptr(new_ctx);
448 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
449 return discard_const_p(void, ptr);
453 _TLIST_REMOVE(tc->parent->child, tc);
454 if (tc->parent->child) {
455 tc->parent->child->parent = tc->parent;
458 if (tc->prev) tc->prev->next = tc->next;
459 if (tc->next) tc->next->prev = tc->prev;
463 if (new_tc->child) new_tc->child->parent = NULL;
464 _TLIST_ADD(new_tc->child, tc);
466 return discard_const_p(void, ptr);
470 internal talloc_free call
472 static inline int _talloc_free(const void *ptr)
474 struct talloc_chunk *tc;
475 void *oldparent = NULL;
477 if (unlikely(ptr == NULL)) {
481 tc = talloc_chunk_from_ptr(ptr);
483 if (unlikely(tc->refs)) {
485 /* check this is a reference from a child or grantchild
486 * back to it's parent or grantparent
488 * in that case we need to remove the reference and
489 * call another instance of talloc_free() on the current
492 is_child = _talloc_is_parent(tc->refs, ptr);
493 _talloc_free(tc->refs);
495 return _talloc_free(ptr);
500 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
501 /* we have a free loop - stop looping */
505 if (unlikely(tc->destructor)) {
506 talloc_destructor_t d = tc->destructor;
507 if (d == (talloc_destructor_t)-1) {
510 tc->destructor = (talloc_destructor_t)-1;
511 if (d(discard_const_p(void, ptr)) == -1) {
515 tc->destructor = NULL;
518 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC))
519 oldparent = talloc_parent_nolock(ptr);
522 _TLIST_REMOVE(tc->parent->child, tc);
523 if (tc->parent->child) {
524 tc->parent->child->parent = tc->parent;
527 if (tc->prev) tc->prev->next = tc->next;
528 if (tc->next) tc->next->prev = tc->prev;
531 tc->flags |= TALLOC_FLAG_LOOP;
534 /* we need to work out who will own an abandoned child
535 if it cannot be freed. In priority order, the first
536 choice is owner of any remaining reference to this
537 pointer, the second choice is our parent, and the
538 final choice is the null context. */
539 void *child = TC_PTR_FROM_CHUNK(tc->child);
540 const void *new_parent = null_context;
541 if (unlikely(tc->child->refs)) {
542 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
543 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
545 if (unlikely(_talloc_free(child) == -1)) {
546 if (new_parent == null_context) {
547 struct talloc_chunk *p = talloc_parent_chunk(ptr);
548 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
550 __talloc_steal(new_parent, child);
554 tc->flags |= TALLOC_FLAG_FREE;
556 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC))
557 tc_external_realloc(oldparent, tc, 0);
564 void *_talloc_steal(const void *new_ctx, const void *ptr)
569 p = __talloc_steal(new_ctx, ptr);
575 remove a secondary reference to a pointer. This undo's what
576 talloc_reference() has done. The context and pointer arguments
577 must match those given to a talloc_reference()
579 static inline int talloc_unreference(const void *context, const void *ptr)
581 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
582 struct talloc_reference_handle *h;
584 if (unlikely(context == NULL)) {
585 context = null_context;
588 for (h=tc->refs;h;h=h->next) {
589 struct talloc_chunk *p = talloc_parent_chunk(h);
591 if (context == NULL) break;
592 } else if (TC_PTR_FROM_CHUNK(p) == context) {
600 return _talloc_free(h);
604 remove a specific parent context from a pointer. This is a more
605 controlled varient of talloc_free()
607 int talloc_unlink(const void *context, void *ptr)
609 struct talloc_chunk *tc_p, *new_p;
616 if (context == NULL) {
617 context = null_context;
621 if (talloc_unreference(context, ptr) == 0) {
626 if (context == NULL) {
627 if (talloc_parent_chunk(ptr) != NULL) {
632 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
638 tc_p = talloc_chunk_from_ptr(ptr);
640 if (tc_p->refs == NULL) {
641 int ret = _talloc_free(ptr);
646 new_p = talloc_parent_chunk(tc_p->refs);
648 new_parent = TC_PTR_FROM_CHUNK(new_p);
653 if (talloc_unreference(new_parent, ptr) != 0) {
658 __talloc_steal(new_parent, ptr);
665 add a name to an existing pointer - va_list version
667 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
669 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
671 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
672 tc->name = talloc_vasprintf(ptr, fmt, ap);
673 if (likely(tc->name)) {
674 _talloc_set_name_const(tc->name, ".name");
680 add a name to an existing pointer
682 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
687 name = talloc_set_name_v(ptr, fmt, ap);
694 create a named talloc pointer. Any talloc pointer can be named, and
695 talloc_named() operates just like talloc() except that it allows you
698 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
705 ptr = __talloc(context, size);
707 if (unlikely(ptr == NULL)) return NULL;
710 name = talloc_set_name_v(ptr, fmt, ap);
713 if (unlikely(name == NULL)) {
722 return the name of a talloc ptr, or "UNNAMED"
724 const char *talloc_get_name(const void *ptr)
726 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
727 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
730 if (likely(tc->name)) {
738 check if a pointer has the given name. If it does, return the pointer,
739 otherwise return NULL
741 void *talloc_check_name(const void *ptr, const char *name)
744 if (unlikely(ptr == NULL)) return NULL;
745 pname = talloc_get_name(ptr);
746 if (likely(pname == name || strcmp(pname, name) == 0)) {
747 return discard_const_p(void, ptr);
754 this is for compatibility with older versions of talloc
756 void *talloc_init(const char *fmt, ...)
763 * samba3 expects talloc_report_depth_cb(NULL, ...)
764 * reports all talloc'ed memory, so we need to enable
767 talloc_enable_null_tracking();
769 ptr = __talloc(NULL, 0);
770 if (unlikely(ptr == NULL)) return NULL;
773 name = talloc_set_name_v(ptr, fmt, ap);
776 if (unlikely(name == NULL)) {
785 Allocate a bit of memory as a child of an existing pointer
787 void *_talloc(const void *context, size_t size)
789 return __talloc(context, size);
792 static int talloc_destroy_pointer(void ***pptr)
794 if ((uintptr_t)**pptr < getpagesize())
795 TALLOC_ABORT("Double free or invalid talloc_set?");
796 /* Invalidate pointer so it can't be used again. */
801 void _talloc_set(void *ptr, const void *ctx, size_t size, const char *name)
806 *pptr = talloc_named_const(ctx, size, name);
807 if (unlikely(!*pptr))
810 child = talloc(*pptr, void **);
811 if (unlikely(!child)) {
817 talloc_set_name_const(child, "talloc_set destructor");
818 talloc_set_destructor(child, talloc_destroy_pointer);
822 externally callable talloc_set_name_const()
824 void talloc_set_name_const(const void *ptr, const char *name)
826 _talloc_set_name_const(ptr, name);
830 create a named talloc pointer. Any talloc pointer can be named, and
831 talloc_named() operates just like talloc() except that it allows you
834 void *talloc_named_const(const void *context, size_t size, const char *name)
838 p = _talloc_named_const(context, size, name);
844 free a talloc pointer. This also frees all child pointers of this
847 return 0 if the memory is actually freed, otherwise -1. The memory
848 will not be freed if the ref_count is > 1 or the destructor (if
849 any) returns non-zero
851 int talloc_free(const void *ptr)
853 int saved_errno = errno, ret;
856 ret = _talloc_free(discard_const_p(void, ptr));
866 A talloc version of realloc. The context argument is only used if
869 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
871 struct talloc_chunk *tc;
874 /* size zero is equivalent to free() */
875 if (unlikely(size == 0)) {
880 if (unlikely(size >= MAX_TALLOC_SIZE)) {
884 /* realloc(NULL) is equivalent to malloc() */
886 return talloc_named_const(context, size, name);
889 tc = talloc_chunk_from_ptr(ptr);
891 /* don't allow realloc on referenced pointers */
892 if (unlikely(tc->refs)) {
897 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) {
898 /* need to get parent before setting free flag. */
899 void *parent = talloc_parent_nolock(ptr);
900 tc->flags |= TALLOC_FLAG_FREE;
901 new_ptr = tc_external_realloc(parent, tc, size + TC_HDR_SIZE);
903 /* by resetting magic we catch users of the old memory */
904 tc->flags |= TALLOC_FLAG_FREE;
907 new_ptr = malloc(size + TC_HDR_SIZE);
909 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
913 new_ptr = realloc(tc, size + TC_HDR_SIZE);
917 if (unlikely(!new_ptr)) {
918 tc->flags &= ~TALLOC_FLAG_FREE;
923 tc = (struct talloc_chunk *)new_ptr;
924 tc->flags &= ~TALLOC_FLAG_FREE;
926 tc->parent->child = tc;
929 tc->child->parent = tc;
940 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
943 return TC_PTR_FROM_CHUNK(tc);
947 a wrapper around talloc_steal() for situations where you are moving a pointer
948 between two structures, and want the old pointer to be set to NULL
950 void *_talloc_move(const void *new_ctx, const void *_pptr)
952 const void **pptr = discard_const_p(const void *,_pptr);
953 void *ret = _talloc_steal(new_ctx, *pptr);
959 return the total size of a talloc pool (subtree)
961 static size_t _talloc_total_size(const void *ptr)
964 struct talloc_chunk *c, *tc;
966 tc = talloc_chunk_from_ptr(ptr);
968 if (tc->flags & TALLOC_FLAG_LOOP) {
972 tc->flags |= TALLOC_FLAG_LOOP;
975 for (c=tc->child;c;c=c->next) {
976 total += _talloc_total_size(TC_PTR_FROM_CHUNK(c));
979 tc->flags &= ~TALLOC_FLAG_LOOP;
984 size_t talloc_total_size(const void *ptr)
996 total = _talloc_total_size(ptr);
1002 return the total number of blocks in a talloc pool (subtree)
1004 static size_t _talloc_total_blocks(const void *ptr)
1007 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1009 if (tc->flags & TALLOC_FLAG_LOOP) {
1013 tc->flags |= TALLOC_FLAG_LOOP;
1016 for (c=tc->child;c;c=c->next) {
1017 total += _talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1020 tc->flags &= ~TALLOC_FLAG_LOOP;
1025 size_t talloc_total_blocks(const void *ptr)
1030 total = _talloc_total_blocks(ptr);
1036 static size_t _talloc_reference_count(const void *ptr)
1038 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1039 struct talloc_reference_handle *h;
1042 for (h=tc->refs;h;h=h->next) {
1049 return the number of external references to a pointer
1051 size_t talloc_reference_count(const void *ptr)
1055 lock(talloc_chunk_from_ptr(ptr));
1056 ret = _talloc_reference_count(ptr);
1062 report on memory usage by all children of a pointer, giving a full tree view
1064 static void _talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1065 void (*callback)(const void *ptr,
1066 int depth, int max_depth,
1068 void *private_data),
1071 struct talloc_chunk *c, *tc;
1073 tc = talloc_chunk_from_ptr(ptr);
1075 if (tc->flags & TALLOC_FLAG_LOOP) {
1079 callback(ptr, depth, max_depth, 0, private_data);
1081 if (max_depth >= 0 && depth >= max_depth) {
1085 tc->flags |= TALLOC_FLAG_LOOP;
1086 for (c=tc->child;c;c=c->next) {
1087 if (c->name == TALLOC_MAGIC_REFERENCE) {
1088 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1089 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1091 _talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1094 tc->flags &= ~TALLOC_FLAG_LOOP;
1097 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1098 void (*callback)(const void *ptr,
1099 int depth, int max_depth,
1101 void *private_data),
1107 if (ptr == NULL) return;
1110 _talloc_report_depth_cb(ptr, depth, max_depth, callback, private_data);
1114 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1116 const char *name = talloc_get_name(ptr);
1117 FILE *f = (FILE *)_f;
1120 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1125 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1126 (max_depth < 0 ? "full " :""), name,
1127 (unsigned long)_talloc_total_size(ptr),
1128 (unsigned long)_talloc_total_blocks(ptr));
1132 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1135 (unsigned long)_talloc_total_size(ptr),
1136 (unsigned long)_talloc_total_blocks(ptr),
1137 (int)_talloc_reference_count(ptr), ptr);
1140 fprintf(f, "content: ");
1141 if (talloc_total_size(ptr)) {
1142 int tot = talloc_total_size(ptr);
1145 for (i = 0; i < tot; i++) {
1146 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1147 fprintf(f, "%c", ((char *)ptr)[i]);
1149 fprintf(f, "~%02x", ((char *)ptr)[i]);
1158 report on memory usage by all children of a pointer, giving a full tree view
1160 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1162 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1167 report on memory usage by all children of a pointer, giving a full tree view
1169 void talloc_report_full(const void *ptr, FILE *f)
1171 talloc_report_depth_file(ptr, 0, -1, f);
1175 report on memory usage by all children of a pointer
1177 void talloc_report(const void *ptr, FILE *f)
1179 talloc_report_depth_file(ptr, 0, 1, f);
1183 report on any memory hanging off the null context
1185 static void talloc_report_null(void)
1187 if (talloc_total_size(null_context) != 0) {
1188 talloc_report(null_context, stderr);
1193 report on any memory hanging off the null context
1195 static void talloc_report_null_full(void)
1197 if (talloc_total_size(null_context) != 0) {
1198 talloc_report_full(null_context, stderr);
1203 enable tracking of the NULL context
1205 void talloc_enable_null_tracking(void)
1207 if (null_context == NULL) {
1208 null_context = _talloc_named_const(NULL, 0, "null_context");
1213 disable tracking of the NULL context
1215 void talloc_disable_null_tracking(void)
1217 _talloc_free(null_context);
1218 null_context = NULL;
1222 enable leak reporting on exit
1224 void talloc_enable_leak_report(void)
1226 talloc_enable_null_tracking();
1227 atexit(talloc_report_null);
1231 enable full leak reporting on exit
1233 void talloc_enable_leak_report_full(void)
1235 talloc_enable_null_tracking();
1236 atexit(talloc_report_null_full);
1240 talloc and zero memory.
1242 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1247 p = _talloc_named_const(ctx, size, name);
1251 memset(p, '\0', size);
1258 memdup with a talloc.
1260 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1265 newp = _talloc_named_const(t, size, name);
1269 memcpy(newp, p, size);
1276 strdup with a talloc
1278 char *talloc_strdup(const void *t, const char *p)
1284 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1286 _talloc_set_name_const(ret, ret);
1292 append to a talloced string
1294 char *talloc_append_string(char *orig, const char *append)
1297 size_t olen = strlen(orig);
1303 alenz = strlen(append) + 1;
1305 ret = talloc_realloc(NULL, orig, char, olen + alenz);
1309 /* append the string with the trailing \0 */
1310 memcpy(&ret[olen], append, alenz);
1312 _talloc_set_name_const(ret, ret);
1318 strndup with a talloc
1320 char *talloc_strndup(const void *t, const char *p, size_t n)
1325 for (len=0; len<n && p[len]; len++) ;
1328 ret = (char *)__talloc(t, len + 1);
1330 if (!ret) { return NULL; }
1331 memcpy(ret, p, len);
1333 _talloc_set_name_const(ret, ret);
1337 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1344 /* this call looks strange, but it makes it work on older solaris boxes */
1346 len = vsnprintf(&c, 1, fmt, ap2);
1353 ret = (char *)__talloc(t, len+1);
1357 vsnprintf(ret, len+1, fmt, ap2);
1359 _talloc_set_name_const(ret, ret);
1367 Perform string formatting, and return a pointer to newly allocated
1368 memory holding the result, inside a memory pool.
1370 char *talloc_asprintf(const void *t, const char *fmt, ...)
1376 ret = talloc_vasprintf(t, fmt, ap);
1383 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1384 * and return @p s, which may have moved. Good for gradually
1385 * accumulating output into a string buffer.
1387 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1389 struct talloc_chunk *tc;
1395 return talloc_vasprintf(NULL, fmt, ap);
1398 tc = talloc_chunk_from_ptr(s);
1400 s_len = tc->size - 1;
1403 len = vsnprintf(&c, 1, fmt, ap2);
1407 /* Either the vsnprintf failed or the format resulted in
1408 * no characters being formatted. In the former case, we
1409 * ought to return NULL, in the latter we ought to return
1410 * the original string. Most current callers of this
1411 * function expect it to never return NULL.
1416 s = talloc_realloc(NULL, s, char, s_len + len+1);
1417 if (!s) return NULL;
1420 vsnprintf(s+s_len, len+1, fmt, ap2);
1422 _talloc_set_name_const(s, s);
1428 Realloc @p s to append the formatted result of @p fmt and return @p
1429 s, which may have moved. Good for gradually accumulating output
1430 into a string buffer.
1432 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1437 s = talloc_vasprintf_append(s, fmt, ap);
1443 alloc an array, checking for integer overflow in the array size
1445 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1449 if (count >= MAX_TALLOC_SIZE/el_size) {
1453 p = _talloc_named_const(ctx, el_size * count, name);
1459 alloc an zero array, checking for integer overflow in the array size
1461 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1465 if (count >= MAX_TALLOC_SIZE/el_size) {
1468 p = _talloc_zero(ctx, el_size * count, name);
1473 realloc an array, checking for integer overflow in the array size
1475 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1477 if (count >= MAX_TALLOC_SIZE/el_size) {
1480 return _talloc_realloc(ctx, ptr, el_size * count, name);
1484 a function version of talloc_realloc(), so it can be passed as a function pointer
1485 to libraries that want a realloc function (a realloc function encapsulates
1486 all the basic capabilities of an allocation library, which is why this is useful)
1488 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1490 return _talloc_realloc(context, ptr, size, NULL);
1494 static int talloc_autofree_destructor(void *ptr)
1496 autofree_context = NULL;
1500 static void talloc_autofree(void)
1502 if (autofree_context && *autofree_context == getpid())
1503 talloc_free(autofree_context);
1507 return a context which will be auto-freed on exit
1508 this is useful for reducing the noise in leak reports
1510 void *talloc_autofree_context(void)
1512 if (autofree_context == NULL || *autofree_context != getpid()) {
1513 autofree_context = talloc(NULL, pid_t);
1514 *autofree_context = getpid();
1515 talloc_set_name_const(autofree_context, "autofree_context");
1517 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1518 atexit(talloc_autofree);
1520 return autofree_context;
1523 size_t talloc_get_size(const void *context)
1525 struct talloc_chunk *tc;
1527 if (context == NULL)
1530 tc = talloc_chunk_from_ptr(context);
1536 find a parent of this context that has the given name, if any
1538 void *talloc_find_parent_byname(const void *context, const char *name)
1540 struct talloc_chunk *tc;
1542 if (context == NULL) {
1547 tc = talloc_chunk_from_ptr(context);
1549 if (tc->name && strcmp(tc->name, name) == 0) {
1551 return TC_PTR_FROM_CHUNK(tc);
1553 while (tc && tc->prev) tc = tc->prev;
1563 show the parentage of a context
1565 void talloc_show_parents(const void *context, FILE *file)
1567 struct talloc_chunk *tc;
1569 if (context == NULL) {
1570 fprintf(file, "talloc no parents for NULL\n");
1575 tc = talloc_chunk_from_ptr(context);
1576 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1578 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1579 while (tc && tc->prev) tc = tc->prev;
1588 int talloc_is_parent(const void *context, const void *ptr)
1592 ret = _talloc_is_parent(context, ptr);
1597 void *talloc_add_external(const void *ctx,
1598 void *(*realloc)(const void *, void *, size_t),
1599 void (*lock)(const void *p),
1600 void (*unlock)(void))
1602 struct talloc_chunk *tc, *parent;
1605 if (tc_external_realloc && tc_external_realloc != realloc)
1606 TALLOC_ABORT("talloc_add_external realloc replaced");
1607 tc_external_realloc = realloc;
1609 if (unlikely(ctx == NULL)) {
1613 parent = talloc_chunk_from_ptr(ctx);
1615 tc = tc_external_realloc(ctx, NULL, TC_HDR_SIZE);
1616 p = init_talloc(parent, tc, 0, 1);