From 17331a1768c73bdd7b9c4d8e623c74dc4f746277 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 21 Aug 2008 03:11:47 +0000 Subject: [PATCH] * IOBuffer::Delete(): Check for NULL pointer. The IORequest destructor calls the method unchecked, and the buffer can actually be NULL, if Init() failed. * panic() when running out of VIP memory, at least when KDEBUG is set. * Use heap_set_get_caller() for the VIP heap, so the heap leak checking produces useful caller addresses. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27099 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/device_manager/io_requests.cpp | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/device_manager/io_requests.cpp b/src/system/kernel/device_manager/io_requests.cpp index 4e460ccdb0..64a5d1d398 100644 --- a/src/system/kernel/device_manager/io_requests.cpp +++ b/src/system/kernel/device_manager/io_requests.cpp @@ -8,6 +8,8 @@ #include +#include +#include #include #include #include @@ -86,6 +88,9 @@ IOBuffer::Create(uint32 count, bool vip) void IOBuffer::Delete() { + if (this == NULL) + return; + if (fVIP) vip_io_request_free(this); else @@ -1194,10 +1199,47 @@ IORequest::Dump() const // #pragma mark - allocator +#if KERNEL_HEAP_LEAK_CHECK +static addr_t +get_caller() +{ + // Find the first return address outside of the allocator code. Note, that + // this makes certain assumptions about how the code for the functions + // ends up in the kernel object. + addr_t returnAddresses[5]; + int32 depth = arch_debug_get_stack_trace(returnAddresses, 5, 1, false); + + // find the first return address inside the VIP allocator + int32 i = 0; + for (i = 0; i < depth; i++) { + if (returnAddresses[i] >= (addr_t)&get_caller + && returnAddresses[i] < (addr_t)&vip_io_request_allocator_init) { + break; + } + } + + // now continue until we have the first one outside + for (; i < depth; i++) { + if (returnAddresses[i] < (addr_t)&get_caller + || returnAddresses[i] > (addr_t)&vip_io_request_allocator_init) { + return returnAddresses[i]; + } + } + + return 0; +} +#endif + + void* vip_io_request_malloc(size_t size) { - return heap_memalign(sVIPHeap, 0, size); + void* address = heap_memalign(sVIPHeap, 0, size); +#if KDEBUG + if (address == NULL) + panic("vip_io_request_malloc(): VIP heap %p out of memory", sVIPHeap); +#endif + return address; } @@ -1247,6 +1289,10 @@ vip_io_request_allocator_init() return; } +#if KERNEL_HEAP_LEAK_CHECK + heap_set_get_caller(sVIPHeap, &get_caller); +#endif + dprintf("vip_io_request_allocator_init(): created VIP I/O heap: %p\n", sVIPHeap); }