📄 talloc.c
字号:
static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f){ const char *name = talloc_get_name(ptr); FILE *f = (FILE *)_f; if (is_ref) { fprintf(f, "%*sreference to: %s\n", depth*4, "", name); return; } if (depth == 0) { fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", (max_depth < 0 ? "full " :""), name, (unsigned long)talloc_total_size(ptr), (unsigned long)talloc_total_blocks(ptr)); return; } fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", depth*4, "", name, (unsigned long)talloc_total_size(ptr), (unsigned long)talloc_total_blocks(ptr), (int)talloc_reference_count(ptr), ptr);#if 0 fprintf(f, "content: "); if (talloc_total_size(ptr)) { int tot = talloc_total_size(ptr); int i; for (i = 0; i < tot; i++) { if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { fprintf(f, "%c", ((char *)ptr)[i]); } else { fprintf(f, "~%02x", ((char *)ptr)[i]); } } } fprintf(f, "\n");#endif}/* report on memory usage by all children of a pointer, giving a full tree view*/void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f){ talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); fflush(f);}/* report on memory usage by all children of a pointer, giving a full tree view*/void talloc_report_full(const void *ptr, FILE *f){ talloc_report_depth_file(ptr, 0, -1, f);}/* report on memory usage by all children of a pointer*/void talloc_report(const void *ptr, FILE *f){ talloc_report_depth_file(ptr, 0, 1, f);}/* report on any memory hanging off the null context*/static void talloc_report_null(void){ if (talloc_total_size(null_context) != 0) { talloc_report(null_context, stderr); }}/* report on any memory hanging off the null context*/static void talloc_report_null_full(void){ if (talloc_total_size(null_context) != 0) { talloc_report_full(null_context, stderr); }}/* enable tracking of the NULL context*/void talloc_enable_null_tracking(void){ if (null_context == NULL) { null_context = _talloc_named_const(NULL, 0, "null_context"); }}/* disable tracking of the NULL context*/void talloc_disable_null_tracking(void){ _talloc_free(null_context); null_context = NULL;}/* enable leak reporting on exit*/void talloc_enable_leak_report(void){ talloc_enable_null_tracking(); atexit(talloc_report_null);}/* enable full leak reporting on exit*/void talloc_enable_leak_report_full(void){ talloc_enable_null_tracking(); atexit(talloc_report_null_full);}/* talloc and zero memory. */void *_talloc_zero(const void *ctx, size_t size, const char *name){ void *p = _talloc_named_const(ctx, size, name); if (p) { memset(p, '\0', size); } return p;}/* memdup with a talloc. */void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name){ void *newp = _talloc_named_const(t, size, name); if (likely(newp)) { memcpy(newp, p, size); } return newp;}/* strdup with a talloc */char *talloc_strdup(const void *t, const char *p){ char *ret; if (!p) { return NULL; } ret = (char *)talloc_memdup(t, p, strlen(p) + 1); if (likely(ret)) { _talloc_set_name_const(ret, ret); } return ret;}/* append to a talloced string */char *talloc_append_string(const void *t, char *orig, const char *append){ char *ret; size_t olen = strlen(orig); size_t alenz; if (!append) return orig; alenz = strlen(append) + 1; ret = talloc_realloc(t, orig, char, olen + alenz); if (!ret) return NULL; /* append the string with the trailing \0 */ memcpy(&ret[olen], append, alenz); return ret;}/* strndup with a talloc */char *talloc_strndup(const void *t, const char *p, size_t n){ size_t len; char *ret; for (len=0; len<n && p[len]; len++) ; ret = (char *)__talloc(t, len + 1); if (!ret) { return NULL; } memcpy(ret, p, len); ret[len] = 0; _talloc_set_name_const(ret, ret); return ret;}#ifndef HAVE_VA_COPY#ifdef HAVE___VA_COPY#define va_copy(dest, src) __va_copy(dest, src)#else#define va_copy(dest, src) (dest) = (src)#endif#endifchar *talloc_vasprintf(const void *t, const char *fmt, va_list ap){ int len; char *ret; va_list ap2; char c; /* this call looks strange, but it makes it work on older solaris boxes */ va_copy(ap2, ap); len = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); if (len < 0) { return NULL; } ret = (char *)__talloc(t, len+1); if (ret) { va_copy(ap2, ap); vsnprintf(ret, len+1, fmt, ap2); va_end(ap2); _talloc_set_name_const(ret, ret); } return ret;}/* Perform string formatting, and return a pointer to newly allocated memory holding the result, inside a memory pool. */char *talloc_asprintf(const void *t, const char *fmt, ...){ va_list ap; char *ret; va_start(ap, fmt); ret = talloc_vasprintf(t, fmt, ap); va_end(ap); return ret;}/** * Realloc @p s to append the formatted result of @p fmt and @p ap, * and return @p s, which may have moved. Good for gradually * accumulating output into a string buffer. **/char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap){ struct talloc_chunk *tc; int len, s_len; va_list ap2; char c; if (s == NULL) { return talloc_vasprintf(NULL, fmt, ap); } tc = talloc_chunk_from_ptr(s); s_len = tc->size - 1; va_copy(ap2, ap); len = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); if (len <= 0) { /* Either the vsnprintf failed or the format resulted in * no characters being formatted. In the former case, we * ought to return NULL, in the latter we ought to return * the original string. Most current callers of this * function expect it to never return NULL. */ return s; } s = talloc_realloc(NULL, s, char, s_len + len+1); if (!s) return NULL; va_copy(ap2, ap); vsnprintf(s+s_len, len+1, fmt, ap2); va_end(ap2); _talloc_set_name_const(s, s); return s;}/* Realloc @p s to append the formatted result of @p fmt and return @p s, which may have moved. Good for gradually accumulating output into a string buffer. */char *talloc_asprintf_append(char *s, const char *fmt, ...){ va_list ap; va_start(ap, fmt); s = talloc_vasprintf_append(s, fmt, ap); va_end(ap); return s;}/* alloc an array, checking for integer overflow in the array size*/void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name){ if (count >= MAX_TALLOC_SIZE/el_size) { return NULL; } return _talloc_named_const(ctx, el_size * count, name);}/* alloc an zero array, checking for integer overflow in the array size*/void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name){ if (count >= MAX_TALLOC_SIZE/el_size) { return NULL; } return _talloc_zero(ctx, el_size * count, name);}/* realloc an array, checking for integer overflow in the array size*/void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name){ if (count >= MAX_TALLOC_SIZE/el_size) { return NULL; } return _talloc_realloc(ctx, ptr, el_size * count, name);}/* a function version of talloc_realloc(), so it can be passed as a function pointer to libraries that want a realloc function (a realloc function encapsulates all the basic capabilities of an allocation library, which is why this is useful)*/void *talloc_realloc_fn(const void *context, void *ptr, size_t size){ return _talloc_realloc(context, ptr, size, NULL);}static int talloc_autofree_destructor(void *ptr){ autofree_context = NULL; return 0;}static void talloc_autofree(void){ _talloc_free(autofree_context);}/* return a context which will be auto-freed on exit this is useful for reducing the noise in leak reports*/void *talloc_autofree_context(void){ if (autofree_context == NULL) { autofree_context = _talloc_named_const(NULL, 0, "autofree_context"); talloc_set_destructor(autofree_context, talloc_autofree_destructor); atexit(talloc_autofree); } return autofree_context;}size_t talloc_get_size(const void *context){ struct talloc_chunk *tc; if (context == NULL) return 0; tc = talloc_chunk_from_ptr(context); return tc->size;}/* find a parent of this context that has the given name, if any*/void *talloc_find_parent_byname(const void *context, const char *name){ struct talloc_chunk *tc; if (context == NULL) { return NULL; } tc = talloc_chunk_from_ptr(context); while (tc) { if (tc->name && strcmp(tc->name, name) == 0) { return TC_PTR_FROM_CHUNK(tc); } while (tc && tc->prev) tc = tc->prev; if (tc) { tc = tc->parent; } } return NULL;}/* show the parentage of a context*/void talloc_show_parents(const void *context, FILE *file){ struct talloc_chunk *tc; if (context == NULL) { fprintf(file, "talloc no parents for NULL\n"); return; } tc = talloc_chunk_from_ptr(context); fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); while (tc) { fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); while (tc && tc->prev) tc = tc->prev; if (tc) { tc = tc->parent; } } fflush(file);}/* return 1 if ptr is a parent of context*/int talloc_is_parent(const void *context, const void *ptr){ struct talloc_chunk *tc; if (context == NULL) { return 0; } tc = talloc_chunk_from_ptr(context); while (tc) { if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; while (tc && tc->prev) tc = tc->prev; if (tc) { tc = tc->parent; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -