Added paranoia checks. They reveal that a net buffer data node is freed
twice when running the OpenSSH "forwarding" test, which corrupts the slab's object list. It's not quite clear to me yet why that happens. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25208 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2b8ae28a15
commit
2be0b7cc43
@ -39,6 +39,11 @@
|
||||
#define TRACE_CACHE(cache, format, bananas...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define OBJECT_CACHE_PARANOIA 1
|
||||
#define ENABLE_PARANOIA_CHECK_COMPONENT OBJECT_CACHE_PARANOIA
|
||||
#include <debug_paranoia.h>
|
||||
|
||||
|
||||
#define CACHE_ALIGN_ON_SIZE (30 << 1)
|
||||
|
||||
static const int kMagazineCapacity = 32;
|
||||
@ -173,9 +178,9 @@ static depot_magazine *alloc_magazine();
|
||||
static void free_magazine(depot_magazine *magazine);
|
||||
|
||||
|
||||
|
||||
#ifdef OBJECT_CACHE_TRACING
|
||||
|
||||
|
||||
namespace ObjectCacheTracing {
|
||||
|
||||
class ObjectCacheTraceEntry : public AbstractTraceEntry {
|
||||
@ -832,10 +837,14 @@ object_cache_alloc(object_cache *cache, uint32 flags)
|
||||
source = cache->partial.Head();
|
||||
}
|
||||
|
||||
ParanoiaChecker _2(source);
|
||||
|
||||
object_link *link = _pop(source->free);
|
||||
source->count--;
|
||||
cache->used_count++;
|
||||
|
||||
REMOVE_PARANOIA_CHECK(source, &link->next, sizeof(void*));
|
||||
|
||||
TRACE_CACHE(cache, "allocate %p (%p) from %p, %lu remaining.",
|
||||
link_to_object(link, cache->object_size), link, source, source->count);
|
||||
|
||||
@ -856,6 +865,8 @@ object_cache_return_to_slab(object_cache *cache, slab *source, void *object)
|
||||
if (source == NULL)
|
||||
panic("object_cache: free'd object has no slab");
|
||||
|
||||
ParanoiaChecker _(source);
|
||||
|
||||
object_link *link = object_to_link(object, cache->object_size);
|
||||
|
||||
TRACE_CACHE(cache, "returning %p (%p) to %p, %lu used (%lu empty slabs).",
|
||||
@ -866,6 +877,8 @@ object_cache_return_to_slab(object_cache *cache, slab *source, void *object)
|
||||
source->count++;
|
||||
cache->used_count--;
|
||||
|
||||
ADD_PARANOIA_CHECK(source, &link->next, sizeof(void*));
|
||||
|
||||
if (source->count == source->size) {
|
||||
cache->partial.Remove(source);
|
||||
|
||||
@ -957,6 +970,8 @@ object_cache::InitSlab(slab *slab, void *pages, size_t byteCount)
|
||||
|
||||
uint8 *data = ((uint8 *)pages) + slab->offset;
|
||||
|
||||
CREATE_PARANOIA_CHECK_SET(slab, "slab");
|
||||
|
||||
for (size_t i = 0; i < slab->size; i++) {
|
||||
bool failedOnFirst = false;
|
||||
|
||||
@ -978,10 +993,16 @@ object_cache::InitSlab(slab *slab, void *pages, size_t byteCount)
|
||||
data += object_size;
|
||||
}
|
||||
|
||||
DELETE_PARANOIA_CHECK_SET(slab);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_push(slab->free, object_to_link(data, object_size));
|
||||
|
||||
ADD_PARANOIA_CHECK(slab, &object_to_link(data, object_size)->next,
|
||||
sizeof(void*));
|
||||
|
||||
data += object_size;
|
||||
}
|
||||
|
||||
@ -997,6 +1018,8 @@ object_cache::UninitSlab(slab *slab)
|
||||
if (slab->count != slab->size)
|
||||
panic("cache: destroying a slab which isn't empty.");
|
||||
|
||||
DELETE_PARANOIA_CHECK_SET(slab);
|
||||
|
||||
uint8 *data = ((uint8 *)slab->pages) + slab->offset;
|
||||
|
||||
for (size_t i = 0; i < slab->size; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user