diff --git a/src/rt/memory_region.cpp b/src/rt/memory_region.cpp index 1527addb0f645b94e6a2be45c3740365f1108821..ef8a92b427fd03b0f7fde73c982b8da97e70955e 100644 --- a/src/rt/memory_region.cpp +++ b/src/rt/memory_region.cpp @@ -43,6 +43,7 @@ void memory_region::free(void *mem) { _srv->fatal("live_allocs < 1", __FILE__, __LINE__, ""); } release_alloc(mem); + maybe_poison(mem); _srv->free(alloc); } @@ -52,9 +53,11 @@ memory_region::realloc(void *mem, size_t size) { if (!mem) { add_alloc(); } + size_t old_size = size; size += sizeof(alloc_header); alloc_header *alloc = get_header(mem); assert(alloc->magic == MAGIC); + alloc->size = old_size; alloc_header *newMem = (alloc_header *)_srv->realloc(alloc, size); #ifdef TRACK_ALLOCATIONS if (_allocation_list[newMem->index] != alloc) { @@ -82,6 +85,7 @@ memory_region::malloc(size_t size, const char *tag, bool zero) { mem->magic = MAGIC; mem->tag = tag; mem->index = -1; + mem->size = old_size; claim_alloc(mem->data); if(zero) { @@ -169,6 +173,22 @@ memory_region::claim_alloc(void *mem) { add_alloc(); } +void +memory_region::maybe_poison(void *mem) { + // TODO: We should lock this, in case the compiler doesn't. + static int poison = -1; + if (poison < 0) { + char *env_str = getenv("RUST_POISON_ON_FREE"); + poison = env_str != NULL && env_str[0] != '\0'; + } + + if (!poison) + return; + + alloc_header *alloc = get_header(mem); + memset(mem, '\xcd', alloc->size); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/memory_region.h b/src/rt/memory_region.h index 26a21f45028953a5e982c06e699227c0ba64947c..0197057268cb8bdcd347292ff2f4b664da810e44 100644 --- a/src/rt/memory_region.h +++ b/src/rt/memory_region.h @@ -19,7 +19,7 @@ private: uint32_t magic; int index; const char *tag; - uint32_t pad; // To stay 16 byte aligned. + uint32_t size; char data[]; }; @@ -36,6 +36,8 @@ private: void add_alloc(); void dec_alloc(); + void maybe_poison(void *mem); + public: memory_region(rust_srv *srv, bool synchronized); memory_region(memory_region *parent);