1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r6595: This is Volkers new-talloc patch. Just got the go-ahead from

Volker to commit. Woo Hoo !
Jeremy.
(This used to be commit 316df944a4)
This commit is contained in:
Jeremy Allison 2005-05-03 07:33:49 +00:00 committed by Gerald (Jerry) Carter
parent 114067ced1
commit 7b9d6ac23e
14 changed files with 1889 additions and 528 deletions

View File

@ -276,24 +276,26 @@ copy an IP address from one buffer to another
/* limiting size of ipc replies */
#define SMB_REALLOC_LIMIT(ptr,size) SMB_REALLOC(ptr,MAX((size),4*1024))
/* #define PARANOID_MALLOC_CHECKER 1 */
/* The new talloc is paranoid malloc checker safe. */
#define TALLOC(ctx, size) talloc_named_const(ctx, size, __location__)
#define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
#define TALLOC_ARRAY(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
#define TALLOC_MEMDUP(ctx, ptr, size) _talloc_memdup(ctx, ptr, size, __location__)
#define TALLOC_ZERO(ctx, size) _talloc_zero(ctx, size, __location__)
#define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
#define TALLOC_ZERO_ARRAY(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
#define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__)
#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type)
#define talloc_destroy(ctx) talloc_free(ctx)
#define PARANOID_MALLOC_CHECKER 1
#if defined(PARANOID_MALLOC_CHECKER)
#define TALLOC(ctx, size) talloc_((ctx),(size))
#define TALLOC_P(ctx, type) (type *)talloc_((ctx),sizeof(type))
#define TALLOC_ARRAY(ctx, type, count) (type *)talloc_array_((ctx),sizeof(type),(count))
#define TALLOC_MEMDUP(ctx, ptr, size) talloc_memdup_((ctx),(ptr),(size))
#define TALLOC_ZERO(ctx, size) talloc_zero_((ctx),(size))
#define TALLOC_ZERO_P(ctx, type) (type *)talloc_zero_((ctx),sizeof(type))
#define TALLOC_ZERO_ARRAY(ctx, type, count) (type *)talloc_zero_array_((ctx),sizeof(type),(count))
#define TALLOC_REALLOC(ctx, ptr, count) talloc_realloc_((ctx),(ptr),(count))
#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)talloc_realloc_array_((ctx),(ptr),sizeof(type),(count))
#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem_((ps),sizeof(type),(count))
#define PRS_ALLOC_MEM_VOID(ps, size) prs_alloc_mem_((ps),(size),1)
/* Get medieval on our ass about malloc.... */
/* Restrictions on malloc/realloc/calloc. */
@ -330,15 +332,10 @@ copy an IP address from one buffer to another
#else
#define TALLOC(ctx, size) talloc((ctx),(size))
#define TALLOC_P(ctx, type) (type *)talloc((ctx),sizeof(type))
#define TALLOC_ARRAY(ctx, type, count) (type *)talloc_array((ctx),sizeof(type),(count))
#define TALLOC_MEMDUP(ctx, ptr, size) talloc_memdup((ctx),(ptr),(size))
#define TALLOC_ZERO(ctx, size) talloc_zero((ctx),(size))
#define TALLOC_ZERO_P(ctx, type) (type *)talloc_zero((ctx),sizeof(type))
#define TALLOC_ZERO_ARRAY(ctx, type, count) (type *)talloc_zero_array((ctx),sizeof(type),(count))
#define TALLOC_REALLOC(ctx, ptr, count) talloc_realloc((ctx),(ptr),(count))
#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)talloc_realloc_array((ctx),(ptr),sizeof(type),(count))
#define _STRING_LINE_(s) #s
#define _STRING_LINE2_(s) _STRING_LINE_(s)
#define __LINESTR__ _STRING_LINE2_(__LINE__)
#define __location__ __FILE__ ":" __LINESTR__
#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem((ps),sizeof(type),(count))
#define PRS_ALLOC_MEM_VOID(ps, size) prs_alloc_mem((ps),(size),1)

View File

@ -3,8 +3,8 @@
/*
Unix SMB/CIFS implementation.
Samba temporary memory allocation functions
Copyright (C) Andrew Tridgell 2000
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
Copyright (C) Andrew Tridgell 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,52 +21,107 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/**
* @ingroup talloc
* @{
* @sa talloc.c
/* this is only needed for compatibility with the old talloc */
typedef void TALLOC_CTX;
/*
this uses a little trick to allow __LINE__ to be stringified
*/
#define _STRING_LINE_(s) #s
#define _STRING_LINE2_(s) _STRING_LINE_(s)
#define __LINESTR__ _STRING_LINE2_(__LINE__)
#define __location__ __FILE__ ":" __LINESTR__
/**
* talloc allocation pool. All allocated blocks can be freed in one go.
**/
#ifndef TALLOC_DEPRECATED
#define TALLOC_DEPRECATED 0
#endif
struct talloc_chunk {
struct talloc_chunk *next;
size_t size;
void *ptr;
};
/* useful macros for creating type checked pointers */
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
struct talloc_ctx {
struct talloc_chunk *list;
size_t total_alloc_size;
#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
/** The name recorded for this pool, if any. Should describe
* the purpose for which it was allocated. The string is
* allocated within the pool. **/
char *name;
#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
/** Pointer to the next allocate talloc pool, so that we can
* summarize all talloc memory usage. **/
struct talloc_ctx *next_ctx;
};
#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
typedef struct talloc_ctx TALLOC_CTX;
#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
TALLOC_CTX *talloc_init(char const *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
char *talloc_vasprintf(TALLOC_CTX *t, const char *fmt, va_list ap)
PRINTF_ATTRIBUTE(2, 0);
#define malloc_p(type) (type *)malloc(sizeof(type))
#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count)
#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count)
char *talloc_asprintf(TALLOC_CTX *t, const char *fmt, ...)
PRINTF_ATTRIBUTE(2, 3);
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
char *talloc_vasprintf_append(TALLOC_CTX *t, char *, const char *, va_list ap)
PRINTF_ATTRIBUTE(3, 0);
char *talloc_asprintf_append(TALLOC_CTX *t, char *, const char *, ...)
PRINTF_ATTRIBUTE(3, 4);
#if TALLOC_DEPRECATED
#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
#define talloc_p(ctx, type) talloc(ctx, type)
#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
#define talloc_destroy(ctx) talloc_free(ctx)
#endif
/** @} */
#ifndef PRINTF_ATTRIBUTE
#if (__GNUC__ >= 3)
/** Use gcc attribute to check printf fns. a1 is the 1-based index of
* the parameter containing the format, and a2 the index of the first
* argument. Note that some gcc 2.x versions don't handle this
* properly **/
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
#else
#define PRINTF_ATTRIBUTE(a1, a2)
#endif
#endif
/* The following definitions come from talloc.c */
void *_talloc(const void *context, size_t size);
void talloc_set_destructor(const void *ptr, int (*destructor)(void *));
void talloc_increase_ref_count(const void *ptr);
void *talloc_reference(const void *context, const void *ptr);
int talloc_unlink(const void *context, void *ptr);
void talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void talloc_set_name_const(const void *ptr, const char *name);
void *talloc_named(const void *context, size_t size,
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
void *talloc_named_const(const void *context, size_t size, const char *name);
const char *talloc_get_name(const void *ptr);
void *talloc_check_name(const void *ptr, const char *name);
void talloc_report_depth(const void *ptr, FILE *f, int depth);
void *talloc_parent(const void *ptr);
void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
int talloc_free(void *ptr);
void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
void *talloc_steal(const void *new_ctx, const void *ptr);
off_t talloc_total_size(const void *ptr);
off_t talloc_total_blocks(const void *ptr);
void talloc_report_full(const void *ptr, FILE *f);
void talloc_report(const void *ptr, FILE *f);
void talloc_enable_null_tracking(void);
void talloc_enable_leak_report(void);
void talloc_enable_leak_report_full(void);
void *_talloc_zero(const void *ctx, size_t size, const char *name);
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
char *talloc_strdup(const void *t, const char *p);
char *talloc_strndup(const void *t, const char *p, size_t n);
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append(char *s,
const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
void *talloc_autofree_context(void);
#endif
#endif /* ndef _TALLOC_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -33,19 +33,18 @@
void msg_pool_usage(int msg_type, pid_t src_pid,
void *UNUSED(buf), size_t UNUSED(len))
{
char *reply;
TALLOC_CTX *reply_pool = talloc_init("msg_pool_usage");
off_t reply;
fstring reply_str;
SMB_ASSERT(msg_type == MSG_REQ_POOL_USAGE);
DEBUG(2,("Got POOL_USAGE\n"));
reply = talloc_describe_all(reply_pool);
reply = talloc_total_size(NULL);
fstr_sprintf(reply_str, "%lld", reply);
message_send_pid(src_pid, MSG_POOL_USAGE,
reply, strlen(reply)+1, True);
talloc_destroy(reply_pool);
reply_str, strlen(reply_str)+1, True);
}
/**

View File

@ -1,7 +1,9 @@
/*
Unix SMB/CIFS implementation.
Samba temporary memory allocation functions -- torturer
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
local testing of talloc routines.
Copyright (C) Andrew Tridgell 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -18,48 +20,820 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef _SAMBA_BUILD_
#include "includes.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>
#include "talloc.h"
#endif
#define NCTX 10
#define NOBJ 20
/* the test suite can be built standalone, or as part of Samba */
#ifndef _SAMBA_BUILD_
typedef enum {False=0,True=1} BOOL;
static struct timeval timeval_current(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv;
}
static double timeval_elapsed(struct timeval *tv)
{
struct timeval tv2 = timeval_current();
return (tv2.tv_sec - tv->tv_sec) +
(tv2.tv_usec - tv->tv_usec)*1.0e-6;
}
#endif /* _SAMBA_BUILD_ */
#define CHECK_SIZE(ptr, tsize) do { \
if (talloc_total_size(ptr) != (tsize)) { \
printf(__location__ " failed: wrong '%s' tree size: got %u expected %u\n", \
#ptr, \
(unsigned)talloc_total_size(ptr), \
(unsigned)tsize); \
talloc_report_full(ptr, stdout); \
return False; \
} \
} while (0)
#define CHECK_BLOCKS(ptr, tblocks) do { \
if (talloc_total_blocks(ptr) != (tblocks)) { \
printf(__location__ " failed: wrong '%s' tree blocks: got %u expected %u\n", \
#ptr, \
(unsigned)talloc_total_blocks(ptr), \
(unsigned)tblocks); \
talloc_report_full(ptr, stdout); \
return False; \
} \
} while (0)
/*
test references
*/
static BOOL test_ref1(void)
{
void *root, *p1, *p2, *ref, *r1;
printf("TESTING SINGLE REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
p2 = talloc_named_const(p1, 1, "p2");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 2, "x2");
talloc_named_const(p1, 3, "x3");
r1 = talloc_named_const(root, 1, "r1");
ref = talloc_reference(r1, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 5);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 2);
printf("Freeing p2\n");
talloc_free(p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 5);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
talloc_report_full(root, stdout);
CHECK_BLOCKS(r1, 1);
printf("Freeing r1\n");
talloc_free(r1);
talloc_report_full(NULL, stdout);
printf("Testing NULL\n");
if (talloc_reference(root, NULL)) {
return False;
}
CHECK_BLOCKS(root, 1);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
/*
test references
*/
static BOOL test_ref2(void)
{
void *root, *p1, *p2, *ref, *r1;
printf("TESTING DOUBLE REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 1, "x2");
talloc_named_const(p1, 1, "x3");
p2 = talloc_named_const(p1, 1, "p2");
r1 = talloc_named_const(root, 1, "r1");
ref = talloc_reference(r1, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 5);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 2);
printf("Freeing ref\n");
talloc_free(ref);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 5);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 1);
printf("Freeing p2\n");
talloc_free(p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 4);
CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
talloc_report_full(root, stdout);
CHECK_BLOCKS(r1, 1);
printf("Freeing r1\n");
talloc_free(r1);
talloc_report_full(root, stdout);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
/*
test references
*/
static BOOL test_ref3(void)
{
void *root, *p1, *p2, *ref, *r1;
printf("TESTING PARENT REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
p2 = talloc_named_const(root, 1, "p2");
r1 = talloc_named_const(p1, 1, "r1");
ref = talloc_reference(p2, r1);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 2);
CHECK_BLOCKS(p2, 2);
CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p2, 2);
CHECK_BLOCKS(r1, 1);
printf("Freeing p2\n");
talloc_free(p2);
talloc_report_full(root, stdout);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
/*
test references
*/
static BOOL test_ref4(void)
{
void *root, *p1, *p2, *ref, *r1;
printf("TESTING REFERRER REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 1, "x2");
talloc_named_const(p1, 1, "x3");
p2 = talloc_named_const(p1, 1, "p2");
r1 = talloc_named_const(root, 1, "r1");
ref = talloc_reference(r1, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 5);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 2);
printf("Freeing r1\n");
talloc_free(r1);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 5);
CHECK_BLOCKS(p2, 1);
printf("Freeing p2\n");
talloc_free(p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 4);
printf("Freeing p1\n");
talloc_free(p1);
talloc_report_full(root, stdout);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
/*
test references
*/
static BOOL test_unlink1(void)
{
void *root, *p1, *p2, *ref, *r1;
printf("TESTING UNLINK\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 1, "x2");
talloc_named_const(p1, 1, "x3");
p2 = talloc_named_const(p1, 1, "p2");
r1 = talloc_named_const(p1, 1, "r1");
ref = talloc_reference(r1, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 7);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 2);
printf("Unreferencing r1\n");
talloc_unlink(r1, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p1, 6);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
talloc_report_full(root, stdout);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
static int fail_destructor(void *ptr)
{
return -1;
}
/*
miscellaneous tests to try to get a higher test coverage percentage
*/
static BOOL test_misc(void)
{
void *root, *p1;
char *p2;
double *d;
printf("TESTING MISCELLANEOUS\n");
root = talloc_new(NULL);
p1 = talloc_size(root, 0x7fffffff);
if (p1) {
printf("failed: large talloc allowed\n");
return False;
}
p1 = talloc_strdup(root, "foo");
talloc_increase_ref_count(p1);
talloc_increase_ref_count(p1);
talloc_increase_ref_count(p1);
CHECK_BLOCKS(p1, 1);
CHECK_BLOCKS(root, 2);
talloc_free(p1);
CHECK_BLOCKS(p1, 1);
CHECK_BLOCKS(root, 2);
talloc_unlink(NULL, p1);
CHECK_BLOCKS(p1, 1);
CHECK_BLOCKS(root, 2);
p2 = talloc_strdup(p1, "foo");
if (talloc_unlink(root, p2) != -1) {
printf("failed: talloc_unlink() of non-reference context should return -1\n");
return False;
}
if (talloc_unlink(p1, p2) != 0) {
printf("failed: talloc_unlink() of parent should succeed\n");
return False;
}
talloc_free(p1);
CHECK_BLOCKS(p1, 1);
CHECK_BLOCKS(root, 2);
talloc_set_name(p1, "my name is %s", "foo");
if (strcmp(talloc_get_name(p1), "my name is foo") != 0) {
printf("failed: wrong name after talloc_set_name\n");
return False;
}
CHECK_BLOCKS(p1, 2);
CHECK_BLOCKS(root, 3);
talloc_set_name_const(p1, NULL);
if (strcmp(talloc_get_name(p1), "UNNAMED") != 0) {
printf("failed: wrong name after talloc_set_name(NULL)\n");
return False;
}
CHECK_BLOCKS(p1, 2);
CHECK_BLOCKS(root, 3);
if (talloc_free(NULL) != -1) {
printf("talloc_free(NULL) should give -1\n");
return False;
}
talloc_set_destructor(p1, fail_destructor);
if (talloc_free(p1) != -1) {
printf("Failed destructor should cause talloc_free to fail\n");
return False;
}
talloc_set_destructor(p1, NULL);
talloc_report(root, stdout);
p2 = talloc_zero_size(p1, 20);
if (p2[19] != 0) {
printf("Failed to give zero memory\n");
return False;
}
talloc_free(p2);
if (talloc_strdup(root, NULL) != NULL) {
printf("failed: strdup on NULL should give NULL\n");
return False;
}
p2 = talloc_strndup(p1, "foo", 2);
if (strcmp("fo", p2) != 0) {
printf("failed: strndup doesn't work\n");
return False;
}
p2 = talloc_asprintf_append(p2, "o%c", 'd');
if (strcmp("food", p2) != 0) {
printf("failed: talloc_asprintf_append doesn't work\n");
return False;
}
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(p1, 3);
p2 = talloc_asprintf_append(NULL, "hello %s", "world");
if (strcmp("hello world", p2) != 0) {
printf("failed: talloc_asprintf_append doesn't work\n");
return False;
}
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(p1, 3);
talloc_free(p2);
d = talloc_array(p1, double, 0x20000000);
if (d) {
printf("failed: integer overflow not detected\n");
return False;
}
d = talloc_realloc(p1, d, double, 0x20000000);
if (d) {
printf("failed: integer overflow not detected\n");
return False;
}
talloc_free(p1);
CHECK_BLOCKS(root, 1);
p1 = talloc_named(root, 100, "%d bytes", 100);
CHECK_BLOCKS(p1, 2);
CHECK_BLOCKS(root, 3);
talloc_unlink(root, p1);
p1 = talloc_init("%d bytes", 200);
p2 = talloc_asprintf(p1, "my test '%s'", "string");
CHECK_BLOCKS(p1, 3);
CHECK_SIZE(p2, 17);
CHECK_BLOCKS(root, 1);
talloc_unlink(NULL, p1);
p1 = talloc_named_const(root, 10, "p1");
p2 = talloc_named_const(root, 20, "p2");
talloc_reference(p1, p2);
talloc_report_full(root, stdout);
talloc_unlink(root, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(p1, 2);
CHECK_BLOCKS(root, 3);
talloc_unlink(p1, p2);
talloc_unlink(root, p1);
p1 = talloc_named_const(root, 10, "p1");
p2 = talloc_named_const(root, 20, "p2");
talloc_reference(NULL, p2);
talloc_report_full(root, stdout);
talloc_unlink(root, p2);
talloc_report_full(root, stdout);
CHECK_BLOCKS(p2, 1);
CHECK_BLOCKS(p1, 1);
CHECK_BLOCKS(root, 2);
talloc_unlink(NULL, p2);
talloc_unlink(root, p1);
/* Test that talloc_unlink is a no-op */
if (talloc_unlink(root, NULL) != -1) {
printf("failed: talloc_unlink(root, NULL) == -1\n");
return False;
}
talloc_report(root, stdout);
talloc_report(NULL, stdout);
CHECK_SIZE(root, 0);
talloc_free(root);
CHECK_SIZE(NULL, 0);
talloc_enable_leak_report();
talloc_enable_leak_report_full();
return True;
}
/*
test realloc
*/
static BOOL test_realloc(void)
{
void *root, *p1, *p2;
printf("TESTING REALLOC\n");
root = talloc_new(NULL);
p1 = talloc_size(root, 10);
CHECK_SIZE(p1, 10);
p1 = talloc_realloc_size(NULL, p1, 20);
CHECK_SIZE(p1, 20);
talloc_new(p1);
p2 = talloc_realloc_size(p1, NULL, 30);
talloc_new(p1);
p2 = talloc_realloc_size(p1, p2, 40);
CHECK_SIZE(p2, 40);
CHECK_SIZE(root, 60);
CHECK_BLOCKS(p1, 4);
p1 = talloc_realloc_size(NULL, p1, 20);
CHECK_SIZE(p1, 60);
talloc_increase_ref_count(p2);
if (talloc_realloc_size(NULL, p2, 5) != NULL) {
printf("failed: talloc_realloc() on a referenced pointer should fail\n");
return False;
}
CHECK_BLOCKS(p1, 4);
talloc_realloc_size(NULL, p2, 0);
talloc_realloc_size(NULL, p2, 0);
CHECK_BLOCKS(p1, 3);
if (talloc_realloc_size(NULL, p1, 0x7fffffff) != NULL) {
printf("failed: oversize talloc should fail\n");
return False;
}
talloc_realloc_size(NULL, p1, 0);
CHECK_BLOCKS(root, 1);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
/*
test realloc with a child
*/
static BOOL test_realloc_child(void)
{
void *root;
struct el1 {
int count;
struct el2 {
const char *name;
} **list, **list2, **list3;
} *el1;
struct el2 *el2;
printf("TESTING REALLOC WITH CHILD\n");
root = talloc_new(NULL);
el1 = talloc(root, struct el1);
el1->list = talloc(el1, struct el2 *);
el1->list[0] = talloc(el1->list, struct el2);
el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
el1->list2 = talloc(el1, struct el2 *);
el1->list2[0] = talloc(el1->list2, struct el2);
el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
el1->list3 = talloc(el1, struct el2 *);
el1->list3[0] = talloc(el1->list3, struct el2);
el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
el2 = talloc(el1->list, struct el2);
el2 = talloc(el1->list2, struct el2);
el2 = talloc(el1->list3, struct el2);
el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
talloc_free(root);
return True;
}
/*
test type checking
*/
static BOOL test_type(void)
{
void *root;
struct el1 {
int count;
};
struct el2 {
int count;
};
struct el1 *el1;
printf("TESTING talloc type checking\n");
root = talloc_new(NULL);
el1 = talloc(root, struct el1);
el1->count = 1;
if (talloc_get_type(el1, struct el1) != el1) {
printf("type check failed on el1\n");
return False;
}
if (talloc_get_type(el1, struct el2) != NULL) {
printf("type check failed on el1 with el2\n");
return False;
}
talloc_set_type(el1, struct el2);
if (talloc_get_type(el1, struct el2) != (struct el2 *)el1) {
printf("type set failed on el1 with el2\n");
return False;
}
talloc_free(root);
return True;
}
/*
test steal
*/
static BOOL test_steal(void)
{
void *root, *p1, *p2;
printf("TESTING STEAL\n");
root = talloc_new(NULL);
p1 = talloc_array(root, char, 10);
CHECK_SIZE(p1, 10);
p2 = talloc_realloc(root, NULL, char, 20);
CHECK_SIZE(p1, 10);
CHECK_SIZE(root, 30);
if (talloc_steal(p1, NULL) != NULL) {
printf("failed: stealing NULL should give NULL\n");
return False;
}
if (talloc_steal(p1, p1) != p1) {
printf("failed: stealing to ourselves is a nop\n");
return False;
}
CHECK_BLOCKS(root, 3);
CHECK_SIZE(root, 30);
talloc_steal(NULL, p1);
talloc_steal(NULL, p2);
CHECK_BLOCKS(root, 1);
CHECK_SIZE(root, 0);
talloc_free(p1);
talloc_steal(root, p2);
CHECK_BLOCKS(root, 2);
CHECK_SIZE(root, 20);
talloc_free(p2);
CHECK_BLOCKS(root, 1);
CHECK_SIZE(root, 0);
talloc_free(root);
p1 = talloc_size(NULL, 3);
CHECK_SIZE(NULL, 3);
talloc_free(p1);
return True;
}
/*
test talloc_realloc_fn
*/
static BOOL test_realloc_fn(void)
{
void *root, *p1;
printf("TESTING talloc_realloc_fn\n");
root = talloc_new(NULL);
p1 = talloc_realloc_fn(root, NULL, 10);
CHECK_BLOCKS(root, 2);
CHECK_SIZE(root, 10);
p1 = talloc_realloc_fn(root, p1, 20);
CHECK_BLOCKS(root, 2);
CHECK_SIZE(root, 20);
p1 = talloc_realloc_fn(root, p1, 0);
CHECK_BLOCKS(root, 1);
CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
static BOOL test_unref_reparent(void)
{
void *root, *p1, *p2, *c1;
printf("TESTING UNREFERENCE AFTER PARENT FREED\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "orig parent");
p2 = talloc_named_const(root, 1, "parent by reference");
c1 = talloc_named_const(p1, 1, "child");
talloc_reference(p2, c1);
talloc_free(p1);
talloc_unlink(p2, c1);
CHECK_SIZE(root, 1);
talloc_free(p2);
talloc_free(root);
return True;
}
/*
measure the speed of talloc versus malloc
*/
static BOOL test_speed(void)
{
void *ctx = talloc_new(NULL);
unsigned count;
struct timeval tv;
printf("MEASURING TALLOC VS MALLOC SPEED\n");
tv = timeval_current();
count = 0;
do {
void *p1, *p2, *p3;
p1 = talloc_size(ctx, count);
p2 = talloc_strdup(p1, "foo bar");
p3 = talloc_size(p1, 300);
talloc_free(p1);
count += 3;
} while (timeval_elapsed(&tv) < 5.0);
printf("talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
talloc_free(ctx);
tv = timeval_current();
count = 0;
do {
void *p1, *p2, *p3;
p1 = malloc(count);
p2 = strdup("foo bar");
p3 = malloc(300);
free(p1);
free(p2);
free(p3);
count += 3;
} while (timeval_elapsed(&tv) < 5.0);
printf("malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
return True;
}
BOOL torture_local_talloc(void)
{
BOOL ret = True;
ret &= test_ref1();
ret &= test_ref2();
ret &= test_ref3();
ret &= test_ref4();
ret &= test_unlink1();
ret &= test_misc();
ret &= test_realloc();
ret &= test_realloc_child();
ret &= test_steal();
ret &= test_unref_reparent();
ret &= test_realloc_fn();
ret &= test_type();
if (ret) {
ret &= test_speed();
}
return ret;
}
#ifndef _SAMBA_BUILD_
int main(void)
{
int i;
TALLOC_CTX *ctx[NCTX];
for (i = 0; i < NCTX; i++) {
ctx[i] = talloc_init("torture(%d)", i);
if (!torture_local_talloc()) {
printf("ERROR: TESTSUIE FAILED\n");
return -1;
}
for (i = 0; i < NCTX; i++) {
int j;
for (j = 0; j < NOBJ; j++) {
char *p;
size_t size = 1<<(i/3+j);
p = talloc(ctx[i], size);
if (!p) {
fprintf(stderr,
"failed to talloc %.0f bytes\n",
(double) size);
exit(1);
}
memset(p, 'A' + j, size);
}
}
for (i = 0; i < NCTX; i++) {
printf("talloc@%p %-40s %ldkB\n", ctx[i],
talloc_pool_name(ctx[i]),
(unsigned long)talloc_pool_size(ctx[i]) >> 10);
}
printf("%s", talloc_describe_all(ctx[0]));
for (i = NCTX - 1; i >= 0; i--)
talloc_destroy(ctx[i]);
return 0;
}
#endif

View File

@ -1703,7 +1703,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res,
ldap_memfree(utf8_field);
}
ber_free(b, 0);
talloc_destroy_pool(ctx);
talloc_free_children(ctx);
fn(NULL, NULL, data_area); /* completed an entry */
}

View File

@ -3303,7 +3303,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
SMB_INO_T inode = 0;
DOS_ATTR_DESC *ret;
ret = talloc(ctx, sizeof(DOS_ATTR_DESC));
ret = TALLOC_P(ctx, DOS_ATTR_DESC);
if (!ret) {
errno = ENOMEM;
return NULL;

View File

@ -1603,7 +1603,7 @@ void lp_talloc_free(void)
{
if (!lp_talloc)
return;
talloc_destroy(lp_talloc);
talloc_free(lp_talloc);
lp_talloc = NULL;
}

View File

@ -640,7 +640,8 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in
memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid));
/* copy unicode domain name */
dom->name = talloc_strdup_w(ctx, pass->uni_name);
dom->name = TALLOC_MEMDUP(ctx, pass->uni_name,
(strlen_w(pass->uni_name) + 1) * sizeof(smb_ucs2_t));
(*domains)[idx - start_idx] = dom;

View File

@ -130,7 +130,7 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned
if (strequal(printer, pq->msg->printer)) {
if (!flatten_message(pq)) {
DEBUG(0,("print_notify_send_messages: Out of memory\n"));
talloc_destroy_pool(send_ctx);
talloc_free_children(send_ctx);
num_messages = 0;
return;
}
@ -143,7 +143,7 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned
buf = TALLOC(send_ctx, offset);
if (!buf) {
DEBUG(0,("print_notify_send_messages: Out of memory\n"));
talloc_destroy_pool(send_ctx);
talloc_free_children(send_ctx);
num_messages = 0;
return;
}
@ -201,7 +201,7 @@ void print_notify_send_messages(unsigned int timeout)
while (print_notify_messages_pending())
print_notify_send_messages_to_printer(notify_queue_head->msg->printer, timeout);
talloc_destroy_pool(send_ctx);
talloc_free_children(send_ctx);
num_messages = 0;
}

View File

@ -153,11 +153,7 @@ char *prs_alloc_mem(prs_struct *ps, size_t size, unsigned int count)
if (size) {
/* We can't call the type-safe version here. */
#if defined(PARANOID_MALLOC_CHECKER)
ret = talloc_zero_array_(ps->mem_ctx, size, count);
#else
ret = talloc_zero_array(ps->mem_ctx, size, count);
#endif
ret = _talloc_zero_array(ps->mem_ctx, size, count, "parse_prs");
}
return ret;
}

View File

@ -536,11 +536,12 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
a complete PDU.
****************************************************************************/
void free_pipe_context(pipes_struct *p)
static void free_pipe_context(pipes_struct *p)
{
if (p->mem_ctx) {
DEBUG(3,("free_pipe_context: destroying talloc pool of size %lu\n", (unsigned long)talloc_pool_size(p->mem_ctx) ));
talloc_destroy_pool(p->mem_ctx);
DEBUG(3,("free_pipe_context: destroying talloc pool of size "
"%llu\n", talloc_total_size(p->mem_ctx) ));
talloc_free_children(p->mem_ctx);
} else {
p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
if (p->mem_ctx == NULL)

View File

@ -747,6 +747,10 @@ void build_options(BOOL screen);
log_stdout = True;
}
if (interactive && (DEBUGLEVEL >= 9)) {
talloc_enable_leak_report();
}
if (log_stdout && Fork) {
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
exit(1);
@ -952,14 +956,6 @@ void build_options(BOOL screen);
namecache_shutdown();
if (interactive) {
TALLOC_CTX *mem_ctx = talloc_init("end_description");
char *description = talloc_describe_all(mem_ctx);
DEBUG(3, ("tallocs left:\n%s\n", description));
talloc_destroy(mem_ctx);
}
exit_server("normal exit");
return(0);
}

View File

@ -54,7 +54,7 @@ static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
}
c = argv[1][0];
size = atoi(argv[2]);
vfs->data = (char *)talloc(mem_ctx, size);
vfs->data = TALLOC_ARRAY(mem_ctx, char, size);
if (vfs->data == NULL) {
printf("populate: error=-1 (not enough memory)");
return NT_STATUS_UNSUCCESSFUL;
@ -364,7 +364,7 @@ static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
/* do some error checking on these */
fd = atoi(argv[1]);
size = atoi(argv[2]);
vfs->data = (char *)talloc(mem_ctx, size);
vfs->data = TALLOC_ARRAY(mem_ctx, char, size);
if (vfs->data == NULL) {
printf("read: error=-1 (not enough memory)");
return NT_STATUS_UNSUCCESSFUL;