pool: do poolcheck when free nodes get corrupted instead of assert
doing poolcheck should give us better context to figure out what memory blocks / owners corrupted the blocks after free. this is for hunting down a memory corruption seen in connection with usb serial.
This commit is contained in:
parent
a84c51a1e3
commit
2a94e1fc19
1 changed files with 28 additions and 30 deletions
|
@ -159,7 +159,6 @@ static void poolnewarena(Pool*, ulong);
|
|||
static void* poolreallocl(Pool*, void*, ulong);
|
||||
static Free* treedelete(Free*, Free*);
|
||||
static Free* treeinsert(Free*, Free*);
|
||||
static Free* treelookup(Free*, ulong);
|
||||
static Free* treelookupgt(Free*, ulong);
|
||||
|
||||
/*
|
||||
|
@ -230,30 +229,21 @@ checktree(Free *t, int a, int b)
|
|||
static Free**
|
||||
ltreewalk(Free **t, ulong size)
|
||||
{
|
||||
assert(t != nil /* ltreewalk */);
|
||||
Free *f;
|
||||
|
||||
for(;;) {
|
||||
if(*t == nil)
|
||||
f = *t;
|
||||
if(f == nil || f->magic != FREE_MAGIC)
|
||||
return t;
|
||||
|
||||
assert((*t)->magic == FREE_MAGIC);
|
||||
|
||||
if(size == (*t)->size)
|
||||
if(size == f->size)
|
||||
return t;
|
||||
if(size < (*t)->size)
|
||||
t = &(*t)->left;
|
||||
if(size < f->size)
|
||||
t = &f->left;
|
||||
else
|
||||
t = &(*t)->right;
|
||||
t = &f->right;
|
||||
}
|
||||
}
|
||||
|
||||
/* treelookup: find node in tree with size == size */
|
||||
static Free*
|
||||
treelookup(Free *t, ulong size)
|
||||
{
|
||||
return *ltreewalk(&t, size);
|
||||
}
|
||||
|
||||
/* treeinsert: insert node into tree */
|
||||
static Free*
|
||||
treeinsert(Free *tree, Free *node)
|
||||
|
@ -263,11 +253,11 @@ treeinsert(Free *tree, Free *node)
|
|||
assert(node != nil /* treeinsert */);
|
||||
|
||||
loc = ltreewalk(&tree, node->size);
|
||||
if(*loc == nil) {
|
||||
repl = *loc;
|
||||
if(repl == nil || repl->magic != FREE_MAGIC) {
|
||||
node->left = nil;
|
||||
node->right = nil;
|
||||
} else { /* replace existing node */
|
||||
repl = *loc;
|
||||
node->left = repl->left;
|
||||
node->right = repl->right;
|
||||
}
|
||||
|
@ -284,7 +274,8 @@ treedelete(Free *tree, Free *node)
|
|||
assert(node != nil /* treedelete */);
|
||||
|
||||
loc = ltreewalk(&tree, node->size);
|
||||
assert(*loc == node);
|
||||
if(*loc != node || node->magic != FREE_MAGIC)
|
||||
return tree; /* free nodes corrupted */
|
||||
|
||||
if(node->left == nil)
|
||||
*loc = node->right;
|
||||
|
@ -300,7 +291,6 @@ treedelete(Free *tree, Free *node)
|
|||
succ->right = node->right;
|
||||
*loc = succ;
|
||||
}
|
||||
|
||||
node->left = node->right = Poison;
|
||||
return tree;
|
||||
}
|
||||
|
@ -313,7 +303,7 @@ treelookupgt(Free *t, ulong size)
|
|||
|
||||
lastgood = nil;
|
||||
for(;;) {
|
||||
if(t == nil)
|
||||
if(t == nil || t->magic != FREE_MAGIC)
|
||||
return lastgood;
|
||||
if(size == t->size)
|
||||
return t;
|
||||
|
@ -387,6 +377,11 @@ pooladd(Pool *p, Alloc *anode)
|
|||
node->magic = FREE_MAGIC;
|
||||
parent = ltreewalk(&p->freeroot, node->size);
|
||||
olst = *parent;
|
||||
if(olst != nil && olst->magic != FREE_MAGIC){
|
||||
/* corruption of free nodes */
|
||||
poolcheckl(p);
|
||||
olst = *parent = nil;
|
||||
}
|
||||
lst = listadd(olst, node);
|
||||
if(olst != lst) /* need to update tree */
|
||||
*parent = treeinsert(*parent, lst);
|
||||
|
@ -403,14 +398,17 @@ pooldel(Pool *p, Free *node)
|
|||
|
||||
parent = ltreewalk(&p->freeroot, node->size);
|
||||
olst = *parent;
|
||||
assert(olst != nil /* pooldel */);
|
||||
|
||||
lst = listdelete(olst, node);
|
||||
if(lst == nil)
|
||||
*parent = treedelete(*parent, olst);
|
||||
else if(lst != olst)
|
||||
*parent = treeinsert(*parent, lst);
|
||||
|
||||
if(olst == nil || olst->magic != FREE_MAGIC){
|
||||
/* corruption of free nodes */
|
||||
poolcheckl(p);
|
||||
*parent = nil;
|
||||
} else {
|
||||
lst = listdelete(olst, node);
|
||||
if(lst == nil)
|
||||
*parent = treedelete(*parent, olst);
|
||||
else if(lst != olst)
|
||||
*parent = treeinsert(*parent, lst);
|
||||
}
|
||||
node->left = node->right = Poison;
|
||||
p->curfree -= node->size;
|
||||
|
||||
|
|
Loading…
Reference in a new issue