more strict freed memory handling for valgrind

This commit is contained in:
dzaima 2022-07-10 02:40:43 +03:00
parent 162aff4595
commit aabaac977b
5 changed files with 26 additions and 20 deletions

View File

@ -220,6 +220,11 @@ static bool atomEqual(B w, B x) { // doesn't consume (not that that matters real
static void pst(char* msg) { static void pst(char* msg) {
VALGRIND_PRINTF_BACKTRACE("%s", msg); VALGRIND_PRINTF_BACKTRACE("%s", msg);
} }
#else
#define vg_def_p(X, L)
#define vg_undef_p(X, L)
#define vg_def_v(X) (X)
#define vg_undef_v(X) (X)
#endif #endif
// call stuff // call stuff

View File

@ -26,9 +26,11 @@ FORCE_INLINE void BN(splitTo)(EmptyValue* c, i64 from, i64 to, bool notEqual) {
b->type = t_empty; b->type = t_empty;
b->mmInfo = MMI(from); b->mmInfo = MMI(from);
b->next = buckets[from]; b->next = buckets[from];
vg_undef_p(b, sizeof(EmptyValue));
buckets[from] = b; buckets[from] = b;
} }
c->next = buckets[from]; c->next = buckets[from];
vg_undef_p(c, sizeof(EmptyValue));
buckets[from] = c; buckets[from] = c;
} }
@ -44,9 +46,6 @@ static NOINLINE void* BN(allocateMore)(i64 bucket, u8 type, i64 from, i64 to) {
EmptyValue* c = MMAP(sz); EmptyValue* c = MMAP(sz);
if (c==MAP_FAILED) thrOOM(); if (c==MAP_FAILED) thrOOM();
#endif #endif
#ifdef USE_VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(c, sz);
#endif
if (alSize+1>=alCap) { if (alSize+1>=alCap) {
alCap = alCap? alCap*2 : 1024; alCap = alCap? alCap*2 : 1024;
al = realloc(al, sizeof(AllocInfo)*alCap); al = realloc(al, sizeof(AllocInfo)*alCap);
@ -55,6 +54,7 @@ static NOINLINE void* BN(allocateMore)(i64 bucket, u8 type, i64 from, i64 to) {
c->type = t_empty; c->type = t_empty;
c->mmInfo = from; c->mmInfo = from;
c->next = 0; c->next = 0;
vg_undef_p(c, sz);
BN(splitTo)(c, from, to, false); BN(splitTo)(c, from, to, false);
return BN(allocL)(bucket, type); return BN(allocL)(bucket, type);
} }
@ -67,8 +67,8 @@ NOINLINE void* BN(allocS)(i64 bucket, u8 type) {
from++; from++;
if (buckets[from]) { if (buckets[from]) {
c = buckets[from]; c = buckets[from];
assert((c->mmInfo&63)==from); assert((vg_def_v(c->mmInfo)&63)==from);
buckets[from] = c->next; buckets[from] = vg_def_v(c->next);
break; break;
} }
if (from >= ALSZ) return BN(allocateMore)(bucket, type, from, to); if (from >= ALSZ) return BN(allocateMore)(bucket, type, from, to);
@ -83,8 +83,8 @@ void BN(forHeap)(V2v f) {
Value* s = ci.p; Value* s = ci.p;
Value* e = (Value*)(ci.sz + (u8*)ci.p); Value* e = (Value*)(ci.sz + (u8*)ci.p);
while (s!=e) { while (s!=e) {
if (s->type!=t_empty) f(s); if (vg_def_v(s->type)!=t_empty) f(s);
s = (Value*)(BSZ(s->mmInfo&63) + (u8*)s); s = (Value*)(BSZ(vg_def_v(s->mmInfo)&63) + (u8*)s);
} }
} }
} }
@ -94,8 +94,8 @@ void BN(forFreedHeap)(V2v f) {
Value* s = ci.p; Value* s = ci.p;
Value* e = (Value*)(ci.sz + (u8*)ci.p); Value* e = (Value*)(ci.sz + (u8*)ci.p);
while (s!=e) { while (s!=e) {
if (s->type==t_empty) f(s); if (vg_def_v(s->type)==t_empty) f(s);
s = (Value*)(BSZ(s->mmInfo&63) + (u8*)s); s = (Value*)(BSZ(vg_def_v(s->mmInfo)&63) + (u8*)s);
} }
} }
} }

View File

@ -1,11 +1,6 @@
#define buckets BN(buckets) #define buckets BN(buckets)
static void BN(free)(Value* x) { static void BN(free)(Value* x) {
onFree(x); onFree(x);
#ifdef USE_VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(x, BSZ(x->mmInfo&127));
VALGRIND_MAKE_MEM_DEFINED(&x->mmInfo, 1);
VALGRIND_MAKE_MEM_DEFINED(&x->type, 1);
#endif
#ifdef DONT_FREE #ifdef DONT_FREE
if (x->type!=t_freed) x->flags = x->type; if (x->type!=t_freed) x->flags = x->type;
#else #else
@ -15,17 +10,14 @@ static void BN(free)(Value* x) {
buckets[b] = (EmptyValue*)x; buckets[b] = (EmptyValue*)x;
#endif #endif
x->type = t_empty; x->type = t_empty;
vg_undef_p(x, BSZ(x->mmInfo&127));
} }
NOINLINE void* BN(allocS)(i64 bucket, u8 type); NOINLINE void* BN(allocS)(i64 bucket, u8 type);
static void* BN(allocL)(i64 bucket, u8 type) { static void* BN(allocL)(i64 bucket, u8 type) {
EmptyValue* x = buckets[bucket]; EmptyValue* x = buckets[bucket];
if (RARE(x==NULL)) return BN(allocS)(bucket, type); if (RARE(x==NULL)) return BN(allocS)(bucket, type);
buckets[bucket] = x->next; buckets[bucket] = vg_def_v(x->next);
#ifdef USE_VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(x, BSZ(bucket));
VALGRIND_MAKE_MEM_DEFINED(&x->mmInfo, 1);
#endif
BN(ctrs)[bucket]++; BN(ctrs)[bucket]++;
x->flags = x->extra = x->type = x->mmInfo = 0; x->flags = x->extra = x->type = x->mmInfo = 0;
x->refc = 1; x->refc = 1;

View File

@ -2,6 +2,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h> #include <malloc.h>
#if USE_VALGRIND
#warning "USE_VALGRIND=1 and MM=0 don't work well together; CBQN requires the ability to read past the end of allocations, but malloc doesn't provide that."
#endif
void gc_add(B x) { } void gc_add(B x) { }
void gc_addFn(vfn f) { } void gc_addFn(vfn f) { }
void gc_maybeGC() { } void gc_maybeGC() { }

View File

@ -30,4 +30,9 @@ u64 vg_rand(u64 x); // randomize undefined bits in x, and return the value with
void vg_printDefined_u64(char* name, u64 x); void vg_printDefined_u64(char* name, u64 x);
void vg_printDump_p(char* name, void* data, u64 len); void vg_printDump_p(char* name, void* data, u64 len);
#define vg_printDump_v(X) ({ AUTO x_ = (X); vg_printDump_p(#X, &x_, sizeof(x_)); }) #define vg_printDump_v(X) ({ AUTO x_ = (X); vg_printDump_p(#X, &x_, sizeof(x_)); x_; })
static void vg_def_p(void* data, u64 len) { VALGRIND_MAKE_MEM_DEFINED(data, len); }
static void vg_undef_p(void* data, u64 len) { VALGRIND_MAKE_MEM_UNDEFINED(data, len); }
#define vg_def_v(X) ({ AUTO x_ = (X); vg_def_p (&x_, sizeof(x_)); x_; })
#define vg_undef_v(X) ({ AUTO x_ = (X); vg_undef_p(&x_, sizeof(x_)); x_; })