kernel: improvements to memory logging

This commit is contained in:
K. Lange 2018-12-11 23:10:43 +09:00
parent 3e04540bf7
commit 1463266db4
2 changed files with 57 additions and 13 deletions

View File

@ -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);

View File

@ -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("Garbage data detected: ", t, addr, size, extra)
print("Halting on suspected bug: 0x%x size was %d" % (addr, addresses[addr]))
else:
print("Garbage data detected: %c 0x%x %d 0xx" % (t, addr, size, extra))
break