diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-10-01 14:36:11 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-10-01 14:36:11 +0200 |
commit | e410a1f71c16229d6b6cbbd18fef7032b8f0a0dc (patch) | |
tree | 54437675df7ecbb8d8842f2e5d01d63d8d85f23e /kern | |
parent | 91956258d42d3179ec7968b2a84bf4d5768c5fe9 (diff) | |
download | gnumach-e410a1f71c16229d6b6cbbd18fef7032b8f0a0dc.tar.gz gnumach-e410a1f71c16229d6b6cbbd18fef7032b8f0a0dc.tar.bz2 gnumach-e410a1f71c16229d6b6cbbd18fef7032b8f0a0dc.zip |
slab: Make whatis look further
Without a tree, we can still look up by hand in the buffers. This
also allows to find freed objects.
Diffstat (limited to 'kern')
-rw-r--r-- | kern/slab.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/kern/slab.c b/kern/slab.c index 3264ebba..dc44e42b 100644 --- a/kern/slab.c +++ b/kern/slab.c @@ -1504,6 +1504,7 @@ void db_show_slab_info(void) void db_whatis_slab(vm_offset_t a) { struct kmem_cache *cache; + int done = 0; #ifndef SLAB_VERIFY db_printf("enabling SLAB_VERIFY is recommended\n"); @@ -1527,16 +1528,65 @@ void db_whatis_slab(vm_offset_t a) struct kmem_slab *slab; slab = rbtree_entry(node, struct kmem_slab, tree_node); if (a >= (vm_offset_t) slab->addr - && a < (vm_offset_t) slab->addr + cache->slab_size) - db_printf("In cache %s\n", cache->name); + && a < (vm_offset_t) slab->addr + cache->slab_size) { + db_printf("Allocated from cache %s\n", cache->name); + done = 1; + goto out_cache; + } } } + union kmem_bufctl *free; + struct kmem_slab *slab; + + list_for_each_entry(&cache->partial_slabs, slab, list_node) { + if (a >= (vm_offset_t) slab->addr + && a < (vm_offset_t) slab->addr + cache->slab_size) { + db_printf("In cache %s\n", cache->name); + + for (free = slab->first_free; free; free = free->next) { + void *buf = kmem_bufctl_to_buf(free, cache); + + if (a >= (vm_offset_t) buf + && a < (vm_offset_t) buf + cache->buf_size) { + db_printf(" In free list\n"); + break; + } + } + + done = 1; + goto out_cache; + } + } + + list_for_each_entry(&cache->free_slabs, slab, list_node) { + if (a >= (vm_offset_t) slab->addr + && a < (vm_offset_t) slab->addr + cache->slab_size) { + db_printf("In cache %s\n", cache->name); + + for (free = slab->first_free; free; free = free->next) { + void *buf = kmem_bufctl_to_buf(free, cache); + + if (a >= (vm_offset_t) buf + && a < (vm_offset_t) buf + cache->buf_size) { + db_printf(" In free list\n"); + break; + } + } + + done = 1; + goto out_cache; + } + } + +out_cache: simple_unlock(&cache->lock); + if (done) + goto out; } +out: simple_unlock(&kmem_cache_list_lock); - } #endif /* MACH_KDB */ |