diff --git a/kernel/mem/alloc.c b/kernel/mem/alloc.c index f7a92d16..ade07b0b 100644 --- a/kernel/mem/alloc.c +++ b/kernel/mem/alloc.c @@ -144,10 +144,21 @@ static fs_node_t _kmalloc_log = { .write = &_kmalloc_log_write }; uint32_t addr; \ uint32_t size; \ uint32_t extra; \ - } __attribute__((packed)) log = {'h',0,0,0}; \ + uint32_t eip; \ + } __attribute__((packed)) log = {'h',_addr,0,0,0}; \ write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); \ while (1) {} \ } } while (0) + +#define STACK_TRACE(base) \ + uint32_t _eip = 0; \ + unsigned int * ebp = (unsigned int *)(&(base) - 2); \ + for (unsigned int frame = 0; frame < 1; ++frame) { \ + unsigned int eip = ebp[1]; \ + if (eip == 0) break; \ + ebp = (unsigned int *)(ebp[0]); \ + _eip = eip; \ + } #endif /* @@ -168,6 +179,7 @@ void * __attribute__ ((malloc)) malloc(uintptr_t size) { #endif void * ret = klmalloc(size); #ifdef _DEBUG_MALLOC + STACK_TRACE(size); if (ret) { char * c = ret; uintptr_t s = size-8; @@ -180,7 +192,8 @@ void * __attribute__ ((malloc)) malloc(uintptr_t size) { uint32_t addr; uint32_t size; uint32_t extra; - } __attribute__((packed)) log = {'m',(uint32_t)ret,size-8,0xDEADBEEF}; + uint32_t eip; + } __attribute__((packed)) log = {'m',(uint32_t)ret,size-8,0xDEADBEEF,_eip}; write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); #endif spin_unlock(mem_lock); @@ -194,6 +207,7 @@ void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size) { #endif void * ret = klrealloc(ptr, size); #ifdef _DEBUG_MALLOC + STACK_TRACE(ptr); if (ret) { char * c = ret; uintptr_t s = size-8; @@ -206,7 +220,8 @@ void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size) { uint32_t addr; uint32_t size; uint32_t extra; - } __attribute__((packed)) log = {'r',(uint32_t)ptr,size-8,(uint32_t)ret}; + uint32_t eip; + } __attribute__((packed)) log = {'r',(uint32_t)ptr,size-8,(uint32_t)ret,_eip}; write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); #endif spin_unlock(mem_lock); @@ -222,7 +237,8 @@ void * __attribute__ ((malloc)) calloc(uintptr_t nmemb, uintptr_t size) { uint32_t addr; uint32_t size; uint32_t extra; - } __attribute__((packed)) log = {'c',(uint32_t)ret,size,nmemb}; + uint32_t eip; + } __attribute__((packed)) log = {'c',(uint32_t)ret,size,nmemb,0}; write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); #endif spin_unlock(mem_lock); @@ -236,6 +252,7 @@ void * __attribute__ ((malloc)) valloc(uintptr_t size) { #endif void * ret = klvalloc(size); #ifdef _DEBUG_MALLOC + STACK_TRACE(size); if (ret) { char * c = ret; uintptr_t s = size-8; @@ -248,7 +265,8 @@ void * __attribute__ ((malloc)) valloc(uintptr_t size) { uint32_t addr; uint32_t size; uint32_t extra; - } __attribute__((packed)) log = {'v',(uint32_t)ret,size-8,0xDEADBEEF}; + uint32_t eip; + } __attribute__((packed)) log = {'v',(uint32_t)ret,size-8,0xDEADBEEF,_eip}; write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); #endif spin_unlock(mem_lock); @@ -259,12 +277,14 @@ void free(void * ptr) { spin_lock(mem_lock); if ((uintptr_t)ptr > placement_pointer) { #ifdef _DEBUG_MALLOC - HALT_ON(0x143c000); IRQ_OFF; + + STACK_TRACE(ptr); + char * tag = ptr; uintptr_t i = 0; uint32_t * x; - while (i < 102400) { + while (i < 1024000) { x = (uint32_t*)(tag + i); if (*x == 0xDEADBEEF) break; i++; @@ -274,7 +294,8 @@ void free(void * ptr) { uint32_t addr; uint32_t size; uint32_t extra; - } __attribute__((packed)) log = {'f',(uint32_t)ptr,x[1],x[0]}; + uint32_t eip; + } __attribute__((packed)) log = {'f',(uint32_t)ptr,x[1],x[0],_eip}; write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); #endif klfree(ptr); diff --git a/util/process_log.py b/util/process_log.py index 1f6abc3e..48835107 100644 --- a/util/process_log.py +++ b/util/process_log.py @@ -2,26 +2,43 @@ import struct import sys addresses = {} +sources = {} +last_touched = {} + +def find_nearby_allocations(addr): + for key in addresses.keys(): + if abs(addr - key) < 0x100 and addresses[key]: + print(" nearby: 0x%x (size %d, allocated by 0x%x)" % (key, addresses[key], sources[key])) while 1: - data = sys.stdin.read(13) + data = sys.stdin.read(17) t, = struct.unpack_from("c",data,0) addr, = struct.unpack_from("I",data,1) size, = struct.unpack_from("I",data,5) extra, = struct.unpack_from("I",data,9) + fault, = struct.unpack_from("I",data,13) if t == 'm': addresses[addr] = size + sources[addr] = fault + last_touched[addr] = t elif t == 'v': addresses[addr] = size + sources[addr] = fault + last_touched[addr] = t elif t == 'c': addresses[addr] = 'c' + sources[addr] = 0 + last_touched[addr] = t elif t == 'r': if addr not in addresses: print("Bad realloc: 0x%x" % addr) else: addresses[addr] = None addresses[extra] = size + sources[extra] = fault + last_touched[addr] = t + last_touched[extra] = t elif t == 'f': if addr not in addresses: print("Bad free detected: 0x%x" % addr) @@ -30,13 +47,19 @@ while 1: elif addresses[addr] == 'c': print("freeing something that was calloced...") addresses[addr] = None - elif addresses[addr] != size: - print("Size on free is incorrect: 0x%x %d %d" % (addr,addresses[addr], size)) elif extra != 0xDEADBEEF: - print("Extremely large buffer or otherwise bad free (but size is right?): 0x%x" % addr) + print("Large buffer has bad value: 0x%x (0x%x) expected size is %d, supposed is %d" % (addr, extra, addresses[addr], size)) + elif addresses[addr] != size: + print("Size on free is incorrect: 0x%x %d %d 0x%x allocated by 0x%x last touched by %c" % (addr,addresses[addr], size, fault, sources[addr], last_touched[addr])) + find_nearby_allocations(addr) else: addresses[addr] = None + elif t == 'h': + if addr not in addresses: + print("Spurious halt: 0x%x" % (addr)) + else: + print("Halting on suspected bug: 0x%x size was %d" % (addr, addresses[addr])) else: - print("Garbage data detected: ", t, addr, size, extra) + print("Garbage data detected: %c 0x%x %d 0xx" % (t, addr, size, extra)) break