rt: Implement poison-on-free, for debugging memory issues
This commit is contained in:
parent
23210a3293
commit
d3e8887d3c
2 changed files with 23 additions and 1 deletions
|
@ -43,6 +43,7 @@ void memory_region::free(void *mem) {
|
||||||
_srv->fatal("live_allocs < 1", __FILE__, __LINE__, "");
|
_srv->fatal("live_allocs < 1", __FILE__, __LINE__, "");
|
||||||
}
|
}
|
||||||
release_alloc(mem);
|
release_alloc(mem);
|
||||||
|
maybe_poison(mem);
|
||||||
_srv->free(alloc);
|
_srv->free(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +53,11 @@ memory_region::realloc(void *mem, size_t size) {
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
add_alloc();
|
add_alloc();
|
||||||
}
|
}
|
||||||
|
size_t old_size = size;
|
||||||
size += sizeof(alloc_header);
|
size += sizeof(alloc_header);
|
||||||
alloc_header *alloc = get_header(mem);
|
alloc_header *alloc = get_header(mem);
|
||||||
assert(alloc->magic == MAGIC);
|
assert(alloc->magic == MAGIC);
|
||||||
|
alloc->size = old_size;
|
||||||
alloc_header *newMem = (alloc_header *)_srv->realloc(alloc, size);
|
alloc_header *newMem = (alloc_header *)_srv->realloc(alloc, size);
|
||||||
#ifdef TRACK_ALLOCATIONS
|
#ifdef TRACK_ALLOCATIONS
|
||||||
if (_allocation_list[newMem->index] != alloc) {
|
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->magic = MAGIC;
|
||||||
mem->tag = tag;
|
mem->tag = tag;
|
||||||
mem->index = -1;
|
mem->index = -1;
|
||||||
|
mem->size = old_size;
|
||||||
claim_alloc(mem->data);
|
claim_alloc(mem->data);
|
||||||
|
|
||||||
if(zero) {
|
if(zero) {
|
||||||
|
@ -169,6 +173,22 @@ memory_region::claim_alloc(void *mem) {
|
||||||
add_alloc();
|
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:
|
// Local Variables:
|
||||||
// mode: C++
|
// mode: C++
|
||||||
|
|
|
@ -19,7 +19,7 @@ private:
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
int index;
|
int index;
|
||||||
const char *tag;
|
const char *tag;
|
||||||
uint32_t pad; // To stay 16 byte aligned.
|
uint32_t size;
|
||||||
char data[];
|
char data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ private:
|
||||||
|
|
||||||
void add_alloc();
|
void add_alloc();
|
||||||
void dec_alloc();
|
void dec_alloc();
|
||||||
|
void maybe_poison(void *mem);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
memory_region(rust_srv *srv, bool synchronized);
|
memory_region(rust_srv *srv, bool synchronized);
|
||||||
memory_region(memory_region *parent);
|
memory_region(memory_region *parent);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue