X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=lib%2Ftalloc%2Ftalloc.c;h=41684dfee18c360c5aaf3b7040b1ad2b306992b2;hb=7b1674617330f31526040f062ea134a9b3d8d496;hp=5ea07918cfd8218115cbdefb1cfb88cd200db0a9;hpb=6b06b0d3b4971107b561a818c627a11021ef5812;p=rusty%2Fsamba.git diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 5ea07918cfd..41684dfee18 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -58,19 +58,30 @@ code that might not cope */ #define ALWAYS_REALLOC 0 +/* How many bottom bits of flags are not magic value */ +#define TALLOC_FLAG_BITS 5 + +#define TALLOC_FLAG_BITMASK ((1 << TALLOC_FLAG_BITS)-1) +#define TALLOC_MAGIC_BITMASK (~TALLOC_FLAG_BITMASK) + +#define TALLOC_MAGIC_MAJOR_SHIFT (7 + TALLOC_FLAG_BITS) +#define TALLOC_MAGIC_MINOR_SHIFT TALLOC_FLAG_BITS + +#define TALLOC_MAGIC_BASE_BITMASK (~(1 << TALLOC_MAGIC_MAJOR_SHIFT)) #define MAX_TALLOC_SIZE 0x10000000 -#define TALLOC_MAGIC_BASE 0xe814ec70 +#define TALLOC_MAGIC_BASE 0xe814ec60 #define TALLOC_MAGIC ( \ TALLOC_MAGIC_BASE + \ - (TALLOC_VERSION_MAJOR << 12) + \ - (TALLOC_VERSION_MINOR << 4) \ + (TALLOC_VERSION_MAJOR << TALLOC_MAGIC_MAJOR_SHIFT) + \ + (TALLOC_VERSION_MINOR << TALLOC_MAGIC_MINOR_SHIFT) \ ) #define TALLOC_FLAG_FREE 0x01 #define TALLOC_FLAG_LOOP 0x02 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ +#define TALLOC_FLAG_MAY_REF 0x10 /* Warn as if this has multiple references */ #define TALLOC_MAGIC_REFERENCE ((const char *)1) /* by default we abort when given a bad pointer (such as when talloc_free() is called @@ -323,8 +334,8 @@ static void talloc_abort(const char *reason) static void talloc_abort_magic(unsigned magic) { unsigned striped = magic - TALLOC_MAGIC_BASE; - unsigned major = (striped & 0xFFFFF000) >> 12; - unsigned minor = (striped & 0x00000FF0) >> 4; + unsigned major = (striped >> TALLOC_MAGIC_MAJOR_SHIFT); + unsigned minor = ((striped & ((1 << TALLOC_MAGIC_MAJOR_SHIFT)-1)) >> TALLOC_MAGIC_MINOR_SHIFT); talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n", magic, major, minor, TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR); @@ -346,9 +357,9 @@ static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) { const char *pp = (const char *)ptr; struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); - if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { - if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) { - talloc_abort_magic(tc->flags & (~0xF)); + if (unlikely((tc->flags & (TALLOC_FLAG_FREE | TALLOC_MAGIC_BITMASK)) != TALLOC_MAGIC)) { + if ((tc->flags & TALLOC_MAGIC_BITMASK) == TALLOC_MAGIC_BASE) { + talloc_abort_magic(tc->flags & TALLOC_MAGIC_BITMASK); return NULL; } @@ -412,6 +423,10 @@ static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) _PUBLIC_ void *talloc_parent(const void *ptr) { struct talloc_chunk *tc = talloc_parent_chunk(ptr); + + if (ptr && talloc_chunk_from_ptr(ptr)->flags & TALLOC_FLAG_MAY_REF) { + talloc_log("talloc_parent on may_reference pointer"); + } return tc? TC_PTR_FROM_CHUNK(tc) : NULL; } @@ -421,6 +436,10 @@ _PUBLIC_ void *talloc_parent(const void *ptr) _PUBLIC_ const char *talloc_parent_name(const void *ptr) { struct talloc_chunk *tc = talloc_parent_chunk(ptr); + + if (ptr && talloc_chunk_from_ptr(ptr)->flags & TALLOC_FLAG_MAY_REF) { + talloc_log("talloc_parent_name on may_reference pointer"); + } return tc? tc->name : NULL; } @@ -936,6 +955,18 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) return discard_const_p(void, ptr); } +static void log_references(const char *fmt, const char *location, + struct talloc_chunk *tc) +{ + struct talloc_reference_handle *h; + + talloc_log(fmt, location); + + for (h=tc->refs; h; h=h->next) { + talloc_log("\treference at %s\n", h->location); + } +} + /* move a lump of memory from one talloc context to another return the ptr on success, or NULL if it could not be transferred. @@ -952,15 +983,11 @@ _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const cha tc = talloc_chunk_from_ptr(ptr); if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) { - struct talloc_reference_handle *h; - - talloc_log("WARNING: talloc_steal with references at %s\n", - location); - - for (h=tc->refs; h; h=h->next) { - talloc_log("\treference at %s\n", - h->location); - } + log_references("WARNING: talloc_steal with references at %s\n", + location, tc); + } else if (tc->flags & TALLOC_FLAG_MAY_REF) { + log_references("WARNING: talloc_steal on may_reference ptr at %s\n", + location, tc); } #if 0 @@ -1346,6 +1373,11 @@ _PUBLIC_ int _talloc_free(void *ptr, const char *location) } tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_MAY_REF) { + log_references("ERROR: talloc_free with may_reference at %s\n", + location, tc); + } if (unlikely(tc->refs != NULL)) { struct talloc_reference_handle *h; @@ -1357,13 +1389,8 @@ _PUBLIC_ int _talloc_free(void *ptr, const char *location) return talloc_unlink(null_context, ptr); } - talloc_log("ERROR: talloc_free with references at %s\n", - location); - - for (h=tc->refs; h; h=h->next) { - talloc_log("\treference at %s\n", - h->location); - } + log_references("ERROR: talloc_free with references at %s\n", + location, tc); return -1; } @@ -2369,3 +2396,12 @@ _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) { return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); } + +_PUBLIC_ void *talloc_may_reference(const void *ptr) +{ + struct talloc_chunk *tc; + + tc = talloc_chunk_from_ptr(ptr); + tc->flags |= TALLOC_FLAG_MAY_REF; + return discard_const_p(void, ptr); +}