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 struct talloc_chunk *old_parent = NULL;
542 if (unlikely(tc->child->refs)) {
543 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
544 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
546 /* finding the parent here is potentially quite
547 expensive, but the alternative, which is to change
548 talloc to always have a valid tc->parent pointer,
549 makes realloc more expensive where there are a
550 large number of children.
552 The reason we need the parent pointer here is that
553 if _talloc_free_internal() fails due to references
554 or a failing destructor we need to re-parent, but
555 the free call can invalidate the prev pointer.
557 if (new_parent == null_context && (tc->child->refs || tc->child->destructor)) {
558 old_parent = talloc_parent_chunk(ptr);
560 if (unlikely(_talloc_free(child) == -1)) {
561 if (new_parent == null_context) {
562 struct talloc_chunk *p = old_parent;
563 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
565 __talloc_steal(new_parent, child);
569 tc->flags |= TALLOC_FLAG_FREE;
571 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC))
572 tc_external_realloc(oldparent, tc, 0);
579 void *_talloc_steal(const void *new_ctx, const void *ptr)
584 p = __talloc_steal(new_ctx, ptr);
590 remove a secondary reference to a pointer. This undo's what
591 talloc_reference() has done. The context and pointer arguments
592 must match those given to a talloc_reference()
594 static inline int talloc_unreference(const void *context, const void *ptr)
596 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
597 struct talloc_reference_handle *h;
599 if (unlikely(context == NULL)) {
600 context = null_context;
603 for (h=tc->refs;h;h=h->next) {
604 struct talloc_chunk *p = talloc_parent_chunk(h);
606 if (context == NULL) break;
607 } else if (TC_PTR_FROM_CHUNK(p) == context) {
615 return _talloc_free(h);
619 remove a specific parent context from a pointer. This is a more
620 controlled varient of talloc_free()
622 int talloc_unlink(const void *context, void *ptr)
624 struct talloc_chunk *tc_p, *new_p;
631 if (context == NULL) {
632 context = null_context;
636 if (talloc_unreference(context, ptr) == 0) {
641 if (context == NULL) {
642 if (talloc_parent_chunk(ptr) != NULL) {
647 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
653 tc_p = talloc_chunk_from_ptr(ptr);
655 if (tc_p->refs == NULL) {
656 int ret = _talloc_free(ptr);
661 new_p = talloc_parent_chunk(tc_p->refs);
663 new_parent = TC_PTR_FROM_CHUNK(new_p);
668 if (talloc_unreference(new_parent, ptr) != 0) {
673 __talloc_steal(new_parent, ptr);
680 add a name to an existing pointer - va_list version
682 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_FMT(2,0);
684 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
686 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
687 tc->name = talloc_vasprintf(ptr, fmt, ap);
688 if (likely(tc->name)) {
689 _talloc_set_name_const(tc->name, ".name");
695 add a name to an existing pointer
697 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
702 name = talloc_set_name_v(ptr, fmt, ap);
709 create a named talloc pointer. Any talloc pointer can be named, and
710 talloc_named() operates just like talloc() except that it allows you
713 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
720 ptr = __talloc(context, size);
722 if (unlikely(ptr == NULL)) return NULL;
725 name = talloc_set_name_v(ptr, fmt, ap);
728 if (unlikely(name == NULL)) {
737 return the name of a talloc ptr, or "UNNAMED"
739 const char *talloc_get_name(const void *ptr)
741 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
742 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
745 if (likely(tc->name)) {
753 check if a pointer has the given name. If it does, return the pointer,
754 otherwise return NULL
756 void *talloc_check_name(const void *ptr, const char *name)
759 if (unlikely(ptr == NULL)) return NULL;
760 pname = talloc_get_name(ptr);
761 if (likely(pname == name || strcmp(pname, name) == 0)) {
762 return discard_const_p(void, ptr);
769 this is for compatibility with older versions of talloc
771 void *talloc_init(const char *fmt, ...)
778 * samba3 expects talloc_report_depth_cb(NULL, ...)
779 * reports all talloc'ed memory, so we need to enable
782 talloc_enable_null_tracking();
784 ptr = __talloc(NULL, 0);
785 if (unlikely(ptr == NULL)) return NULL;
788 name = talloc_set_name_v(ptr, fmt, ap);
791 if (unlikely(name == NULL)) {
800 Allocate a bit of memory as a child of an existing pointer
802 void *_talloc(const void *context, size_t size)
804 return __talloc(context, size);
807 static int talloc_destroy_pointer(void ***pptr)
809 if ((uintptr_t)**pptr < getpagesize())
810 TALLOC_ABORT("Double free or invalid talloc_set?");
811 /* Invalidate pointer so it can't be used again. */
816 void _talloc_set(void *ptr, const void *ctx, size_t size, const char *name)
821 p = talloc_named_const(ctx, size, name);
825 child = talloc(p, void **);
826 if (unlikely(!child)) {
832 talloc_set_name_const(child, "talloc_set destructor");
833 talloc_set_destructor(child, talloc_destroy_pointer);
836 /* memcpy rather than cast avoids aliasing problems. */
837 memcpy(ptr, &p, sizeof(p));
841 externally callable talloc_set_name_const()
843 void talloc_set_name_const(const void *ptr, const char *name)
845 _talloc_set_name_const(ptr, name);
849 create a named talloc pointer. Any talloc pointer can be named, and
850 talloc_named() operates just like talloc() except that it allows you
853 void *talloc_named_const(const void *context, size_t size, const char *name)
857 p = _talloc_named_const(context, size, name);
863 free a talloc pointer. This also frees all child pointers of this
866 return 0 if the memory is actually freed, otherwise -1. The memory
867 will not be freed if the ref_count is > 1 or the destructor (if
868 any) returns non-zero
870 int talloc_free(const void *ptr)
872 int saved_errno = errno, ret;
875 ret = _talloc_free(discard_const_p(void, ptr));
885 A talloc version of realloc. The context argument is only used if
888 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
890 struct talloc_chunk *tc;
893 /* size zero is equivalent to free() */
894 if (unlikely(size == 0)) {
899 if (unlikely(size >= MAX_TALLOC_SIZE)) {
903 /* realloc(NULL) is equivalent to malloc() */
905 return talloc_named_const(context, size, name);
908 tc = talloc_chunk_from_ptr(ptr);
910 /* don't allow realloc on referenced pointers */
911 if (unlikely(tc->refs)) {
916 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) {
917 /* need to get parent before setting free flag. */
918 void *parent = talloc_parent_nolock(ptr);
919 tc->flags |= TALLOC_FLAG_FREE;
920 new_ptr = tc_external_realloc(parent, tc, size + TC_HDR_SIZE);
922 /* by resetting magic we catch users of the old memory */
923 tc->flags |= TALLOC_FLAG_FREE;
926 new_ptr = malloc(size + TC_HDR_SIZE);
928 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
932 new_ptr = realloc(tc, size + TC_HDR_SIZE);
936 if (unlikely(!new_ptr)) {
937 tc->flags &= ~TALLOC_FLAG_FREE;
942 tc = (struct talloc_chunk *)new_ptr;
943 tc->flags &= ~TALLOC_FLAG_FREE;
945 tc->parent->child = tc;
948 tc->child->parent = tc;
959 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
962 return TC_PTR_FROM_CHUNK(tc);
966 a wrapper around talloc_steal() for situations where you are moving a pointer
967 between two structures, and want the old pointer to be set to NULL
969 void *_talloc_move(const void *new_ctx, const void *_pptr)
971 const void **pptr = discard_const_p(const void *,_pptr);
972 void *ret = _talloc_steal(new_ctx, *pptr);
978 return the total size of a talloc pool (subtree)
980 static size_t _talloc_total_size(const void *ptr)
983 struct talloc_chunk *c, *tc;
985 tc = talloc_chunk_from_ptr(ptr);
987 if (tc->flags & TALLOC_FLAG_LOOP) {
991 tc->flags |= TALLOC_FLAG_LOOP;
994 for (c=tc->child;c;c=c->next) {
995 total += _talloc_total_size(TC_PTR_FROM_CHUNK(c));
998 tc->flags &= ~TALLOC_FLAG_LOOP;
1003 size_t talloc_total_size(const void *ptr)
1015 total = _talloc_total_size(ptr);
1021 return the total number of blocks in a talloc pool (subtree)
1023 static size_t _talloc_total_blocks(const void *ptr)
1026 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1028 if (tc->flags & TALLOC_FLAG_LOOP) {
1032 tc->flags |= TALLOC_FLAG_LOOP;
1035 for (c=tc->child;c;c=c->next) {
1036 total += _talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1039 tc->flags &= ~TALLOC_FLAG_LOOP;
1044 size_t talloc_total_blocks(const void *ptr)
1049 total = _talloc_total_blocks(ptr);
1055 static size_t _talloc_reference_count(const void *ptr)
1057 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1058 struct talloc_reference_handle *h;
1061 for (h=tc->refs;h;h=h->next) {
1068 return the number of external references to a pointer
1070 size_t talloc_reference_count(const void *ptr)
1074 lock(talloc_chunk_from_ptr(ptr));
1075 ret = _talloc_reference_count(ptr);
1081 report on memory usage by all children of a pointer, giving a full tree view
1083 static void _talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1084 void (*callback)(const void *ptr,
1085 int depth, int max_depth,
1087 void *private_data),
1090 struct talloc_chunk *c, *tc;
1092 tc = talloc_chunk_from_ptr(ptr);
1094 if (tc->flags & TALLOC_FLAG_LOOP) {
1098 callback(ptr, depth, max_depth, 0, private_data);
1100 if (max_depth >= 0 && depth >= max_depth) {
1104 tc->flags |= TALLOC_FLAG_LOOP;
1105 for (c=tc->child;c;c=c->next) {
1106 if (c->name == TALLOC_MAGIC_REFERENCE) {
1107 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1108 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1110 _talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1113 tc->flags &= ~TALLOC_FLAG_LOOP;
1116 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1117 void (*callback)(const void *ptr,
1118 int depth, int max_depth,
1120 void *private_data),
1126 if (ptr == NULL) return;
1129 _talloc_report_depth_cb(ptr, depth, max_depth, callback, private_data);
1133 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1135 const char *name = talloc_get_name(ptr);
1136 FILE *f = (FILE *)_f;
1139 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1144 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1145 (max_depth < 0 ? "full " :""), name,
1146 (unsigned long)_talloc_total_size(ptr),
1147 (unsigned long)_talloc_total_blocks(ptr));
1151 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1154 (unsigned long)_talloc_total_size(ptr),
1155 (unsigned long)_talloc_total_blocks(ptr),
1156 (int)_talloc_reference_count(ptr), ptr);
1159 fprintf(f, "content: ");
1160 if (talloc_total_size(ptr)) {
1161 int tot = talloc_total_size(ptr);
1164 for (i = 0; i < tot; i++) {
1165 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1166 fprintf(f, "%c", ((char *)ptr)[i]);
1168 fprintf(f, "~%02x", ((char *)ptr)[i]);
1177 report on memory usage by all children of a pointer, giving a full tree view
1179 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1181 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1186 report on memory usage by all children of a pointer, giving a full tree view
1188 void talloc_report_full(const void *ptr, FILE *f)
1190 talloc_report_depth_file(ptr, 0, -1, f);
1194 report on memory usage by all children of a pointer
1196 void talloc_report(const void *ptr, FILE *f)
1198 talloc_report_depth_file(ptr, 0, 1, f);
1202 report on any memory hanging off the null context
1204 static void talloc_report_null(void)
1206 if (talloc_total_size(null_context) != 0) {
1207 talloc_report(null_context, stderr);
1212 report on any memory hanging off the null context
1214 static void talloc_report_null_full(void)
1216 if (talloc_total_size(null_context) != 0) {
1217 talloc_report_full(null_context, stderr);
1222 enable tracking of the NULL context
1224 void talloc_enable_null_tracking(void)
1226 if (null_context == NULL) {
1227 null_context = _talloc_named_const(NULL, 0, "null_context");
1232 disable tracking of the NULL context
1234 void talloc_disable_null_tracking(void)
1236 _talloc_free(null_context);
1237 null_context = NULL;
1241 enable leak reporting on exit
1243 void talloc_enable_leak_report(void)
1245 talloc_enable_null_tracking();
1246 atexit(talloc_report_null);
1250 enable full leak reporting on exit
1252 void talloc_enable_leak_report_full(void)
1254 talloc_enable_null_tracking();
1255 atexit(talloc_report_null_full);
1259 talloc and zero memory.
1261 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1266 p = _talloc_named_const(ctx, size, name);
1270 memset(p, '\0', size);
1277 memdup with a talloc.
1279 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1284 newp = _talloc_named_const(t, size, name);
1288 memcpy(newp, p, size);
1295 strdup with a talloc
1297 char *talloc_strdup(const void *t, const char *p)
1303 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1305 _talloc_set_name_const(ret, ret);
1311 append to a talloced string
1313 char *talloc_append_string(char *orig, const char *append)
1316 size_t olen = strlen(orig);
1322 alenz = strlen(append) + 1;
1324 ret = talloc_realloc(NULL, orig, char, olen + alenz);
1328 /* append the string with the trailing \0 */
1329 memcpy(&ret[olen], append, alenz);
1331 _talloc_set_name_const(ret, ret);
1337 strndup with a talloc
1339 char *talloc_strndup(const void *t, const char *p, size_t n)
1344 for (len=0; len<n && p[len]; len++) ;
1347 ret = (char *)__talloc(t, len + 1);
1349 if (!ret) { return NULL; }
1350 memcpy(ret, p, len);
1352 _talloc_set_name_const(ret, ret);
1356 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1363 /* this call looks strange, but it makes it work on older solaris boxes */
1365 len = vsnprintf(&c, 1, fmt, ap2);
1372 ret = (char *)__talloc(t, len+1);
1376 vsnprintf(ret, len+1, fmt, ap2);
1378 _talloc_set_name_const(ret, ret);
1386 Perform string formatting, and return a pointer to newly allocated
1387 memory holding the result, inside a memory pool.
1389 char *talloc_asprintf(const void *t, const char *fmt, ...)
1395 ret = talloc_vasprintf(t, fmt, ap);
1402 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1403 * and return @p s, which may have moved. Good for gradually
1404 * accumulating output into a string buffer.
1406 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1408 struct talloc_chunk *tc;
1414 return talloc_vasprintf(NULL, fmt, ap);
1417 tc = talloc_chunk_from_ptr(s);
1419 s_len = tc->size - 1;
1422 len = vsnprintf(&c, 1, fmt, ap2);
1426 /* Either the vsnprintf failed or the format resulted in
1427 * no characters being formatted. In the former case, we
1428 * ought to return NULL, in the latter we ought to return
1429 * the original string. Most current callers of this
1430 * function expect it to never return NULL.
1435 s = talloc_realloc(NULL, s, char, s_len + len+1);
1436 if (!s) return NULL;
1439 vsnprintf(s+s_len, len+1, fmt, ap2);
1441 _talloc_set_name_const(s, s);
1447 Realloc @p s to append the formatted result of @p fmt and return @p
1448 s, which may have moved. Good for gradually accumulating output
1449 into a string buffer.
1451 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1456 s = talloc_vasprintf_append(s, fmt, ap);
1462 alloc an array, checking for integer overflow in the array size
1464 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1468 if (count >= MAX_TALLOC_SIZE/el_size) {
1472 p = _talloc_named_const(ctx, el_size * count, name);
1478 alloc an zero array, checking for integer overflow in the array size
1480 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1484 if (count >= MAX_TALLOC_SIZE/el_size) {
1487 p = _talloc_zero(ctx, el_size * count, name);
1492 realloc an array, checking for integer overflow in the array size
1494 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1496 if (count >= MAX_TALLOC_SIZE/el_size) {
1499 return _talloc_realloc(ctx, ptr, el_size * count, name);
1503 a function version of talloc_realloc(), so it can be passed as a function pointer
1504 to libraries that want a realloc function (a realloc function encapsulates
1505 all the basic capabilities of an allocation library, which is why this is useful)
1507 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1509 return _talloc_realloc(context, ptr, size, NULL);
1513 static int talloc_autofree_destructor(void *ptr)
1515 autofree_context = NULL;
1519 static void talloc_autofree(void)
1521 if (autofree_context && *autofree_context == getpid())
1522 talloc_free(autofree_context);
1526 return a context which will be auto-freed on exit
1527 this is useful for reducing the noise in leak reports
1529 void *talloc_autofree_context(void)
1531 if (autofree_context == NULL || *autofree_context != getpid()) {
1532 autofree_context = talloc(NULL, pid_t);
1533 *autofree_context = getpid();
1534 talloc_set_name_const(autofree_context, "autofree_context");
1536 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1537 atexit(talloc_autofree);
1539 return autofree_context;
1542 size_t talloc_get_size(const void *context)
1544 struct talloc_chunk *tc;
1546 if (context == NULL)
1549 tc = talloc_chunk_from_ptr(context);
1555 find a parent of this context that has the given name, if any
1557 void *talloc_find_parent_byname(const void *context, const char *name)
1559 struct talloc_chunk *tc;
1561 if (context == NULL) {
1566 tc = talloc_chunk_from_ptr(context);
1568 if (tc->name && strcmp(tc->name, name) == 0) {
1570 return TC_PTR_FROM_CHUNK(tc);
1572 while (tc && tc->prev) tc = tc->prev;
1582 show the parentage of a context
1584 void talloc_show_parents(const void *context, FILE *file)
1586 struct talloc_chunk *tc;
1588 if (context == NULL) {
1589 fprintf(file, "talloc no parents for NULL\n");
1594 tc = talloc_chunk_from_ptr(context);
1595 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1597 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1598 while (tc && tc->prev) tc = tc->prev;
1607 int talloc_is_parent(const void *context, const void *ptr)
1611 ret = _talloc_is_parent(context, ptr);
1616 void *talloc_add_external(const void *ctx,
1617 void *(*realloc)(const void *, void *, size_t),
1618 void (*lock)(const void *p),
1619 void (*unlock)(void))
1621 struct talloc_chunk *tc, *parent;
1624 if (tc_external_realloc && tc_external_realloc != realloc)
1625 TALLOC_ABORT("talloc_add_external realloc replaced");
1626 tc_external_realloc = realloc;
1628 if (unlikely(ctx == NULL)) {
1632 parent = talloc_chunk_from_ptr(ctx);
1634 tc = tc_external_realloc(ctx, NULL, TC_HDR_SIZE);
1635 p = init_talloc(parent, tc, 0, 1);