BReferenceable: Relax reference-count destruction checks.

"delete object;" is logically the same as "object->ReleaseReference();"
when there is a reference count of 1, and we need to permit that instead
of asserting on it, so the case where a referenceable object is a member
variable of a class works without asserting.

This manifested in packagefs: the Resolvable class has a linked-list with
Dependency objects (which are referenceable) in it. (Further, the stack
checks do not work quite right for kernel stacks.)

Fixes #17575.
This commit is contained in:
Augustin Cavalier 2022-02-10 14:29:36 -05:00
parent e51f545c90
commit 071d20db2b

View File

@ -38,39 +38,12 @@ BReferenceable::BReferenceable()
BReferenceable::~BReferenceable()
{
#if !defined(_BOOT_MODE) && defined(DEBUG)
bool enterDebugger = false;
char message[256];
if (fReferenceCount == 1) {
// Simple heuristic to test if this object was allocated
// on the stack: check if this is within 1KB in either
// direction of the current stack address, and the reference
// count is 1. If so, we don't flag a warning since that would
// imply the object was allocated/destroyed on the stack
// without any references being acquired or released.
char test;
ssize_t testOffset = (addr_t)this - (addr_t)&test;
if (testOffset > 1024 || -testOffset > 1024) {
// might still be a stack object, check the thread's
// stack range to be sure.
thread_info info;
status_t result = get_thread_info(find_thread(NULL), &info);
if (result == B_OK && (this < info.stack_base
|| this > info.stack_end)) {
snprintf(message, sizeof(message), "Deleted referenceable "
"object that's not on the stack (this: %p, stack_base: %p,"
" stack_end: %p)\n", this, info.stack_base,
info.stack_end);
enterDebugger = true;
}
}
} else if (fReferenceCount != 0) {
snprintf(message, sizeof(message), "Deleted referenceable object %p with "
"non-zero reference count (%" B_PRId32 ")\n", this, fReferenceCount);
enterDebugger = true;
}
if (enterDebugger)
if (fReferenceCount != 0 && fReferenceCount != 1) {
char message[256];
snprintf(message, sizeof(message), "deleting referenceable object %p with "
"reference count (%" B_PRId32 ")\n", this, fReferenceCount);
debugger(message);
}
#endif
}