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_FMT(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 p = talloc_named_const(ctx, size, name);
810 child = talloc(p, void **);
811 if (unlikely(!child)) {
817 talloc_set_name_const(child, "talloc_set destructor");
818 talloc_set_destructor(child, talloc_destroy_pointer);
821 /* memcpy rather than cast avoids aliasing problems. */
822 memcpy(ptr, &p, sizeof(p));
826 externally callable talloc_set_name_const()
828 void talloc_set_name_const(const void *ptr, const char *name)
830 _talloc_set_name_const(ptr, name);
834 create a named talloc pointer. Any talloc pointer can be named, and
835 talloc_named() operates just like talloc() except that it allows you
838 void *talloc_named_const(const void *context, size_t size, const char *name)
842 p = _talloc_named_const(context, size, name);
848 free a talloc pointer. This also frees all child pointers of this
851 return 0 if the memory is actually freed, otherwise -1. The memory
852 will not be freed if the ref_count is > 1 or the destructor (if
853 any) returns non-zero
855 int talloc_free(const void *ptr)
857 int saved_errno = errno, ret;
860 ret = _talloc_free(discard_const_p(void, ptr));
870 A talloc version of realloc. The context argument is only used if
873 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
875 struct talloc_chunk *tc;
878 /* size zero is equivalent to free() */
879 if (unlikely(size == 0)) {
884 if (unlikely(size >= MAX_TALLOC_SIZE)) {
888 /* realloc(NULL) is equivalent to malloc() */
890 return talloc_named_const(context, size, name);
893 tc = talloc_chunk_from_ptr(ptr);
895 /* don't allow realloc on referenced pointers */
896 if (unlikely(tc->refs)) {
901 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) {
902 /* need to get parent before setting free flag. */
903 void *parent = talloc_parent_nolock(ptr);
904 tc->flags |= TALLOC_FLAG_FREE;
905 new_ptr = tc_external_realloc(parent, tc, size + TC_HDR_SIZE);
907 /* by resetting magic we catch users of the old memory */
908 tc->flags |= TALLOC_FLAG_FREE;
911 new_ptr = malloc(size + TC_HDR_SIZE);
913 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
917 new_ptr = realloc(tc, size + TC_HDR_SIZE);
921 if (unlikely(!new_ptr)) {
922 tc->flags &= ~TALLOC_FLAG_FREE;
927 tc = (struct talloc_chunk *)new_ptr;
928 tc->flags &= ~TALLOC_FLAG_FREE;
930 tc->parent->child = tc;
933 tc->child->parent = tc;
944 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
947 return TC_PTR_FROM_CHUNK(tc);
951 a wrapper around talloc_steal() for situations where you are moving a pointer
952 between two structures, and want the old pointer to be set to NULL
954 void *_talloc_move(const void *new_ctx, const void *_pptr)
956 const void **pptr = discard_const_p(const void *,_pptr);
957 void *ret = _talloc_steal(new_ctx, *pptr);
963 return the total size of a talloc pool (subtree)
965 static size_t _talloc_total_size(const void *ptr)
968 struct talloc_chunk *c, *tc;
970 tc = talloc_chunk_from_ptr(ptr);
972 if (tc->flags & TALLOC_FLAG_LOOP) {
976 tc->flags |= TALLOC_FLAG_LOOP;
979 for (c=tc->child;c;c=c->next) {
980 total += _talloc_total_size(TC_PTR_FROM_CHUNK(c));
983 tc->flags &= ~TALLOC_FLAG_LOOP;
988 size_t talloc_total_size(const void *ptr)
1000 total = _talloc_total_size(ptr);
1006 return the total number of blocks in a talloc pool (subtree)
1008 static size_t _talloc_total_blocks(const void *ptr)
1011 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1013 if (tc->flags & TALLOC_FLAG_LOOP) {
1017 tc->flags |= TALLOC_FLAG_LOOP;
1020 for (c=tc->child;c;c=c->next) {
1021 total += _talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1024 tc->flags &= ~TALLOC_FLAG_LOOP;
1029 size_t talloc_total_blocks(const void *ptr)
1034 total = _talloc_total_blocks(ptr);
1040 static size_t _talloc_reference_count(const void *ptr)
1042 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1043 struct talloc_reference_handle *h;
1046 for (h=tc->refs;h;h=h->next) {
1053 return the number of external references to a pointer
1055 size_t talloc_reference_count(const void *ptr)
1059 lock(talloc_chunk_from_ptr(ptr));
1060 ret = _talloc_reference_count(ptr);
1066 report on memory usage by all children of a pointer, giving a full tree view
1068 static void _talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1069 void (*callback)(const void *ptr,
1070 int depth, int max_depth,
1072 void *private_data),
1075 struct talloc_chunk *c, *tc;
1077 tc = talloc_chunk_from_ptr(ptr);
1079 if (tc->flags & TALLOC_FLAG_LOOP) {
1083 callback(ptr, depth, max_depth, 0, private_data);
1085 if (max_depth >= 0 && depth >= max_depth) {
1089 tc->flags |= TALLOC_FLAG_LOOP;
1090 for (c=tc->child;c;c=c->next) {
1091 if (c->name == TALLOC_MAGIC_REFERENCE) {
1092 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1093 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1095 _talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1098 tc->flags &= ~TALLOC_FLAG_LOOP;
1101 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1102 void (*callback)(const void *ptr,
1103 int depth, int max_depth,
1105 void *private_data),
1111 if (ptr == NULL) return;
1114 _talloc_report_depth_cb(ptr, depth, max_depth, callback, private_data);
1118 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1120 const char *name = talloc_get_name(ptr);
1121 FILE *f = (FILE *)_f;
1124 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1129 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1130 (max_depth < 0 ? "full " :""), name,
1131 (unsigned long)_talloc_total_size(ptr),
1132 (unsigned long)_talloc_total_blocks(ptr));
1136 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1139 (unsigned long)_talloc_total_size(ptr),
1140 (unsigned long)_talloc_total_blocks(ptr),
1141 (int)_talloc_reference_count(ptr), ptr);
1144 fprintf(f, "content: ");
1145 if (talloc_total_size(ptr)) {
1146 int tot = talloc_total_size(ptr);
1149 for (i = 0; i < tot; i++) {
1150 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1151 fprintf(f, "%c", ((char *)ptr)[i]);
1153 fprintf(f, "~%02x", ((char *)ptr)[i]);
1162 report on memory usage by all children of a pointer, giving a full tree view
1164 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1166 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1171 report on memory usage by all children of a pointer, giving a full tree view
1173 void talloc_report_full(const void *ptr, FILE *f)
1175 talloc_report_depth_file(ptr, 0, -1, f);
1179 report on memory usage by all children of a pointer
1181 void talloc_report(const void *ptr, FILE *f)
1183 talloc_report_depth_file(ptr, 0, 1, f);
1187 report on any memory hanging off the null context
1189 static void talloc_report_null(void)
1191 if (talloc_total_size(null_context) != 0) {
1192 talloc_report(null_context, stderr);
1197 report on any memory hanging off the null context
1199 static void talloc_report_null_full(void)
1201 if (talloc_total_size(null_context) != 0) {
1202 talloc_report_full(null_context, stderr);
1207 enable tracking of the NULL context
1209 void talloc_enable_null_tracking(void)
1211 if (null_context == NULL) {
1212 null_context = _talloc_named_const(NULL, 0, "null_context");
1217 disable tracking of the NULL context
1219 void talloc_disable_null_tracking(void)
1221 _talloc_free(null_context);
1222 null_context = NULL;
1226 enable leak reporting on exit
1228 void talloc_enable_leak_report(void)
1230 talloc_enable_null_tracking();
1231 atexit(talloc_report_null);
1235 enable full leak reporting on exit
1237 void talloc_enable_leak_report_full(void)
1239 talloc_enable_null_tracking();
1240 atexit(talloc_report_null_full);
1244 talloc and zero memory.
1246 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1251 p = _talloc_named_const(ctx, size, name);
1255 memset(p, '\0', size);
1262 memdup with a talloc.
1264 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1269 newp = _talloc_named_const(t, size, name);
1273 memcpy(newp, p, size);
1280 strdup with a talloc
1282 char *talloc_strdup(const void *t, const char *p)
1288 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1290 _talloc_set_name_const(ret, ret);
1296 append to a talloced string
1298 char *talloc_append_string(char *orig, const char *append)
1301 size_t olen = strlen(orig);
1307 alenz = strlen(append) + 1;
1309 ret = talloc_realloc(NULL, orig, char, olen + alenz);
1313 /* append the string with the trailing \0 */
1314 memcpy(&ret[olen], append, alenz);
1316 _talloc_set_name_const(ret, ret);
1322 strndup with a talloc
1324 char *talloc_strndup(const void *t, const char *p, size_t n)
1329 for (len=0; len<n && p[len]; len++) ;
1332 ret = (char *)__talloc(t, len + 1);
1334 if (!ret) { return NULL; }
1335 memcpy(ret, p, len);
1337 _talloc_set_name_const(ret, ret);
1341 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1348 /* this call looks strange, but it makes it work on older solaris boxes */
1350 len = vsnprintf(&c, 1, fmt, ap2);
1357 ret = (char *)__talloc(t, len+1);
1361 vsnprintf(ret, len+1, fmt, ap2);
1363 _talloc_set_name_const(ret, ret);
1371 Perform string formatting, and return a pointer to newly allocated
1372 memory holding the result, inside a memory pool.
1374 char *talloc_asprintf(const void *t, const char *fmt, ...)
1380 ret = talloc_vasprintf(t, fmt, ap);
1387 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1388 * and return @p s, which may have moved. Good for gradually
1389 * accumulating output into a string buffer.
1391 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1393 struct talloc_chunk *tc;
1399 return talloc_vasprintf(NULL, fmt, ap);
1402 tc = talloc_chunk_from_ptr(s);
1404 s_len = tc->size - 1;
1407 len = vsnprintf(&c, 1, fmt, ap2);
1411 /* Either the vsnprintf failed or the format resulted in
1412 * no characters being formatted. In the former case, we
1413 * ought to return NULL, in the latter we ought to return
1414 * the original string. Most current callers of this
1415 * function expect it to never return NULL.
1420 s = talloc_realloc(NULL, s, char, s_len + len+1);
1421 if (!s) return NULL;
1424 vsnprintf(s+s_len, len+1, fmt, ap2);
1426 _talloc_set_name_const(s, s);
1432 Realloc @p s to append the formatted result of @p fmt and return @p
1433 s, which may have moved. Good for gradually accumulating output
1434 into a string buffer.
1436 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1441 s = talloc_vasprintf_append(s, fmt, ap);
1447 alloc an array, checking for integer overflow in the array size
1449 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1453 if (count >= MAX_TALLOC_SIZE/el_size) {
1457 p = _talloc_named_const(ctx, el_size * count, name);
1463 alloc an zero array, checking for integer overflow in the array size
1465 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1469 if (count >= MAX_TALLOC_SIZE/el_size) {
1472 p = _talloc_zero(ctx, el_size * count, name);
1477 realloc an array, checking for integer overflow in the array size
1479 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1481 if (count >= MAX_TALLOC_SIZE/el_size) {
1484 return _talloc_realloc(ctx, ptr, el_size * count, name);
1488 a function version of talloc_realloc(), so it can be passed as a function pointer
1489 to libraries that want a realloc function (a realloc function encapsulates
1490 all the basic capabilities of an allocation library, which is why this is useful)
1492 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1494 return _talloc_realloc(context, ptr, size, NULL);
1498 static int talloc_autofree_destructor(void *ptr)
1500 autofree_context = NULL;
1504 static void talloc_autofree(void)
1506 if (autofree_context && *autofree_context == getpid())
1507 talloc_free(autofree_context);
1511 return a context which will be auto-freed on exit
1512 this is useful for reducing the noise in leak reports
1514 void *talloc_autofree_context(void)
1516 if (autofree_context == NULL || *autofree_context != getpid()) {
1517 autofree_context = talloc(NULL, pid_t);
1518 *autofree_context = getpid();
1519 talloc_set_name_const(autofree_context, "autofree_context");
1521 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1522 atexit(talloc_autofree);
1524 return autofree_context;
1527 size_t talloc_get_size(const void *context)
1529 struct talloc_chunk *tc;
1531 if (context == NULL)
1534 tc = talloc_chunk_from_ptr(context);
1540 find a parent of this context that has the given name, if any
1542 void *talloc_find_parent_byname(const void *context, const char *name)
1544 struct talloc_chunk *tc;
1546 if (context == NULL) {
1551 tc = talloc_chunk_from_ptr(context);
1553 if (tc->name && strcmp(tc->name, name) == 0) {
1555 return TC_PTR_FROM_CHUNK(tc);
1557 while (tc && tc->prev) tc = tc->prev;
1567 show the parentage of a context
1569 void talloc_show_parents(const void *context, FILE *file)
1571 struct talloc_chunk *tc;
1573 if (context == NULL) {
1574 fprintf(file, "talloc no parents for NULL\n");
1579 tc = talloc_chunk_from_ptr(context);
1580 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1582 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1583 while (tc && tc->prev) tc = tc->prev;
1592 int talloc_is_parent(const void *context, const void *ptr)
1596 ret = _talloc_is_parent(context, ptr);
1601 void *talloc_add_external(const void *ctx,
1602 void *(*realloc)(const void *, void *, size_t),
1603 void (*lock)(const void *p),
1604 void (*unlock)(void))
1606 struct talloc_chunk *tc, *parent;
1609 if (tc_external_realloc && tc_external_realloc != realloc)
1610 TALLOC_ABORT("talloc_add_external realloc replaced");
1611 tc_external_realloc = realloc;
1613 if (unlikely(ctx == NULL)) {
1617 parent = talloc_chunk_from_ptr(ctx);
1619 tc = tc_external_realloc(ctx, NULL, TC_HDR_SIZE);
1620 p = init_talloc(parent, tc, 0, 1);