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 0x10000000
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(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;
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);
793 externally callable talloc_set_name_const()
795 void talloc_set_name_const(const void *ptr, const char *name)
797 _talloc_set_name_const(ptr, name);
801 create a named talloc pointer. Any talloc pointer can be named, and
802 talloc_named() operates just like talloc() except that it allows you
805 void *talloc_named_const(const void *context, size_t size, const char *name)
809 p = _talloc_named_const(context, size, name);
815 free a talloc pointer. This also frees all child pointers of this
818 return 0 if the memory is actually freed, otherwise -1. The memory
819 will not be freed if the ref_count is > 1 or the destructor (if
820 any) returns non-zero
822 int talloc_free(const void *ptr)
824 int saved_errno = errno, ret;
827 ret = _talloc_free(discard_const_p(void, ptr));
837 A talloc version of realloc. The context argument is only used if
840 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
842 struct talloc_chunk *tc;
845 /* size zero is equivalent to free() */
846 if (unlikely(size == 0)) {
851 if (unlikely(size >= MAX_TALLOC_SIZE)) {
855 /* realloc(NULL) is equivalent to malloc() */
857 return talloc_named_const(context, size, name);
860 tc = talloc_chunk_from_ptr(ptr);
862 /* don't allow realloc on referenced pointers */
863 if (unlikely(tc->refs)) {
868 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) {
869 /* need to get parent before setting free flag. */
870 void *parent = talloc_parent_nolock(ptr);
871 tc->flags |= TALLOC_FLAG_FREE;
872 new_ptr = tc_external_realloc(parent, tc, size + TC_HDR_SIZE);
874 /* by resetting magic we catch users of the old memory */
875 tc->flags |= TALLOC_FLAG_FREE;
878 new_ptr = malloc(size + TC_HDR_SIZE);
880 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
884 new_ptr = realloc(tc, size + TC_HDR_SIZE);
888 if (unlikely(!new_ptr)) {
889 tc->flags &= ~TALLOC_FLAG_FREE;
894 tc = (struct talloc_chunk *)new_ptr;
895 tc->flags &= ~TALLOC_FLAG_FREE;
897 tc->parent->child = tc;
900 tc->child->parent = tc;
911 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
914 return TC_PTR_FROM_CHUNK(tc);
918 a wrapper around talloc_steal() for situations where you are moving a pointer
919 between two structures, and want the old pointer to be set to NULL
921 void *_talloc_move(const void *new_ctx, const void *_pptr)
923 const void **pptr = discard_const_p(const void *,_pptr);
924 void *ret = _talloc_steal(new_ctx, *pptr);
930 return the total size of a talloc pool (subtree)
932 static size_t _talloc_total_size(const void *ptr)
935 struct talloc_chunk *c, *tc;
937 tc = talloc_chunk_from_ptr(ptr);
939 if (tc->flags & TALLOC_FLAG_LOOP) {
943 tc->flags |= TALLOC_FLAG_LOOP;
946 for (c=tc->child;c;c=c->next) {
947 total += _talloc_total_size(TC_PTR_FROM_CHUNK(c));
950 tc->flags &= ~TALLOC_FLAG_LOOP;
955 size_t talloc_total_size(const void *ptr)
967 total = _talloc_total_size(ptr);
973 return the total number of blocks in a talloc pool (subtree)
975 static size_t _talloc_total_blocks(const void *ptr)
978 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
980 if (tc->flags & TALLOC_FLAG_LOOP) {
984 tc->flags |= TALLOC_FLAG_LOOP;
987 for (c=tc->child;c;c=c->next) {
988 total += _talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
991 tc->flags &= ~TALLOC_FLAG_LOOP;
996 size_t talloc_total_blocks(const void *ptr)
1001 total = _talloc_total_blocks(ptr);
1007 static size_t _talloc_reference_count(const void *ptr)
1009 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1010 struct talloc_reference_handle *h;
1013 for (h=tc->refs;h;h=h->next) {
1020 return the number of external references to a pointer
1022 size_t talloc_reference_count(const void *ptr)
1026 lock(talloc_chunk_from_ptr(ptr));
1027 ret = _talloc_reference_count(ptr);
1033 report on memory usage by all children of a pointer, giving a full tree view
1035 static void _talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1036 void (*callback)(const void *ptr,
1037 int depth, int max_depth,
1039 void *private_data),
1042 struct talloc_chunk *c, *tc;
1044 tc = talloc_chunk_from_ptr(ptr);
1046 if (tc->flags & TALLOC_FLAG_LOOP) {
1050 callback(ptr, depth, max_depth, 0, private_data);
1052 if (max_depth >= 0 && depth >= max_depth) {
1056 tc->flags |= TALLOC_FLAG_LOOP;
1057 for (c=tc->child;c;c=c->next) {
1058 if (c->name == TALLOC_MAGIC_REFERENCE) {
1059 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1060 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1062 _talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1065 tc->flags &= ~TALLOC_FLAG_LOOP;
1068 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),
1078 if (ptr == NULL) return;
1081 _talloc_report_depth_cb(ptr, depth, max_depth, callback, private_data);
1085 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1087 const char *name = talloc_get_name(ptr);
1088 FILE *f = (FILE *)_f;
1091 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1096 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1097 (max_depth < 0 ? "full " :""), name,
1098 (unsigned long)_talloc_total_size(ptr),
1099 (unsigned long)_talloc_total_blocks(ptr));
1103 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1106 (unsigned long)_talloc_total_size(ptr),
1107 (unsigned long)_talloc_total_blocks(ptr),
1108 (int)_talloc_reference_count(ptr), ptr);
1111 fprintf(f, "content: ");
1112 if (talloc_total_size(ptr)) {
1113 int tot = talloc_total_size(ptr);
1116 for (i = 0; i < tot; i++) {
1117 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1118 fprintf(f, "%c", ((char *)ptr)[i]);
1120 fprintf(f, "~%02x", ((char *)ptr)[i]);
1129 report on memory usage by all children of a pointer, giving a full tree view
1131 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1133 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1138 report on memory usage by all children of a pointer, giving a full tree view
1140 void talloc_report_full(const void *ptr, FILE *f)
1142 talloc_report_depth_file(ptr, 0, -1, f);
1146 report on memory usage by all children of a pointer
1148 void talloc_report(const void *ptr, FILE *f)
1150 talloc_report_depth_file(ptr, 0, 1, f);
1154 report on any memory hanging off the null context
1156 static void talloc_report_null(void)
1158 if (talloc_total_size(null_context) != 0) {
1159 talloc_report(null_context, stderr);
1164 report on any memory hanging off the null context
1166 static void talloc_report_null_full(void)
1168 if (talloc_total_size(null_context) != 0) {
1169 talloc_report_full(null_context, stderr);
1174 enable tracking of the NULL context
1176 void talloc_enable_null_tracking(void)
1178 if (null_context == NULL) {
1179 null_context = _talloc_named_const(NULL, 0, "null_context");
1184 disable tracking of the NULL context
1186 void talloc_disable_null_tracking(void)
1188 _talloc_free(null_context);
1189 null_context = NULL;
1193 enable leak reporting on exit
1195 void talloc_enable_leak_report(void)
1197 talloc_enable_null_tracking();
1198 atexit(talloc_report_null);
1202 enable full leak reporting on exit
1204 void talloc_enable_leak_report_full(void)
1206 talloc_enable_null_tracking();
1207 atexit(talloc_report_null_full);
1211 talloc and zero memory.
1213 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1218 p = _talloc_named_const(ctx, size, name);
1222 memset(p, '\0', size);
1229 memdup with a talloc.
1231 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1236 newp = _talloc_named_const(t, size, name);
1240 memcpy(newp, p, size);
1247 strdup with a talloc
1249 char *talloc_strdup(const void *t, const char *p)
1255 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1257 _talloc_set_name_const(ret, ret);
1263 append to a talloced string
1265 char *talloc_append_string(char *orig, const char *append)
1268 size_t olen = strlen(orig);
1274 alenz = strlen(append) + 1;
1276 ret = talloc_realloc(NULL, orig, char, olen + alenz);
1280 /* append the string with the trailing \0 */
1281 memcpy(&ret[olen], append, alenz);
1283 _talloc_set_name_const(ret, ret);
1289 strndup with a talloc
1291 char *talloc_strndup(const void *t, const char *p, size_t n)
1296 for (len=0; len<n && p[len]; len++) ;
1299 ret = (char *)__talloc(t, len + 1);
1301 if (!ret) { return NULL; }
1302 memcpy(ret, p, len);
1304 _talloc_set_name_const(ret, ret);
1308 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1315 /* this call looks strange, but it makes it work on older solaris boxes */
1317 len = vsnprintf(&c, 1, fmt, ap2);
1324 ret = (char *)__talloc(t, len+1);
1328 vsnprintf(ret, len+1, fmt, ap2);
1330 _talloc_set_name_const(ret, ret);
1338 Perform string formatting, and return a pointer to newly allocated
1339 memory holding the result, inside a memory pool.
1341 char *talloc_asprintf(const void *t, const char *fmt, ...)
1347 ret = talloc_vasprintf(t, fmt, ap);
1354 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1355 * and return @p s, which may have moved. Good for gradually
1356 * accumulating output into a string buffer.
1358 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1360 struct talloc_chunk *tc;
1366 return talloc_vasprintf(NULL, fmt, ap);
1369 tc = talloc_chunk_from_ptr(s);
1371 s_len = tc->size - 1;
1374 len = vsnprintf(&c, 1, fmt, ap2);
1378 /* Either the vsnprintf failed or the format resulted in
1379 * no characters being formatted. In the former case, we
1380 * ought to return NULL, in the latter we ought to return
1381 * the original string. Most current callers of this
1382 * function expect it to never return NULL.
1387 s = talloc_realloc(NULL, s, char, s_len + len+1);
1388 if (!s) return NULL;
1391 vsnprintf(s+s_len, len+1, fmt, ap2);
1393 _talloc_set_name_const(s, s);
1399 Realloc @p s to append the formatted result of @p fmt and return @p
1400 s, which may have moved. Good for gradually accumulating output
1401 into a string buffer.
1403 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1408 s = talloc_vasprintf_append(s, fmt, ap);
1414 alloc an array, checking for integer overflow in the array size
1416 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1420 if (count >= MAX_TALLOC_SIZE/el_size) {
1424 p = _talloc_named_const(ctx, el_size * count, name);
1430 alloc an zero array, checking for integer overflow in the array size
1432 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1436 if (count >= MAX_TALLOC_SIZE/el_size) {
1439 p = _talloc_zero(ctx, el_size * count, name);
1444 realloc an array, checking for integer overflow in the array size
1446 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1448 if (count >= MAX_TALLOC_SIZE/el_size) {
1451 return _talloc_realloc(ctx, ptr, el_size * count, name);
1455 a function version of talloc_realloc(), so it can be passed as a function pointer
1456 to libraries that want a realloc function (a realloc function encapsulates
1457 all the basic capabilities of an allocation library, which is why this is useful)
1459 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1461 return _talloc_realloc(context, ptr, size, NULL);
1465 static int talloc_autofree_destructor(void *ptr)
1467 autofree_context = NULL;
1471 static void talloc_autofree(void)
1473 if (autofree_context && *autofree_context == getpid())
1474 talloc_free(autofree_context);
1478 return a context which will be auto-freed on exit
1479 this is useful for reducing the noise in leak reports
1481 void *talloc_autofree_context(void)
1483 if (autofree_context == NULL || *autofree_context != getpid()) {
1484 autofree_context = talloc(NULL, pid_t);
1485 *autofree_context = getpid();
1486 talloc_set_name_const(autofree_context, "autofree_context");
1488 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1489 atexit(talloc_autofree);
1491 return autofree_context;
1494 size_t talloc_get_size(const void *context)
1496 struct talloc_chunk *tc;
1498 if (context == NULL)
1501 tc = talloc_chunk_from_ptr(context);
1507 find a parent of this context that has the given name, if any
1509 void *talloc_find_parent_byname(const void *context, const char *name)
1511 struct talloc_chunk *tc;
1513 if (context == NULL) {
1518 tc = talloc_chunk_from_ptr(context);
1520 if (tc->name && strcmp(tc->name, name) == 0) {
1522 return TC_PTR_FROM_CHUNK(tc);
1524 while (tc && tc->prev) tc = tc->prev;
1534 show the parentage of a context
1536 void talloc_show_parents(const void *context, FILE *file)
1538 struct talloc_chunk *tc;
1540 if (context == NULL) {
1541 fprintf(file, "talloc no parents for NULL\n");
1546 tc = talloc_chunk_from_ptr(context);
1547 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1549 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1550 while (tc && tc->prev) tc = tc->prev;
1559 int talloc_is_parent(const void *context, const void *ptr)
1563 ret = _talloc_is_parent(context, ptr);
1568 void *talloc_add_external(const void *ctx,
1569 void *(*realloc)(const void *, void *, size_t),
1570 void (*lock)(const void *p),
1571 void (*unlock)(void))
1573 struct talloc_chunk *tc, *parent;
1576 if (tc_external_realloc && tc_external_realloc != realloc)
1577 TALLOC_ABORT("talloc_add_external realloc replaced");
1578 tc_external_realloc = realloc;
1580 if (unlikely(ctx == NULL)) {
1584 parent = talloc_chunk_from_ptr(ctx);
1586 tc = tc_external_realloc(ctx, NULL, TC_HDR_SIZE);
1587 p = init_talloc(parent, tc, 0, 1);