kernel: add extensive allocation tracking option
This commit is contained in:
parent
73a3dc1414
commit
5b45f72a37
@ -124,6 +124,32 @@
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
//#define _DEBUG_MALLOC
|
||||||
|
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
#define EARLY_LOG_DEVICE 0x3F8
|
||||||
|
static uint32_t _kmalloc_log_write(fs_node_t *node, uint64_t offset, uint32_t size, uint8_t *buffer) {
|
||||||
|
for (unsigned int i = 0; i < size; ++i) {
|
||||||
|
outportb(EARLY_LOG_DEVICE, buffer[i]);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
static fs_node_t _kmalloc_log = { .write = &_kmalloc_log_write };
|
||||||
|
|
||||||
|
#define HALT_ON(_addr) do { \
|
||||||
|
if ((uintptr_t)ptr == _addr) { \
|
||||||
|
IRQ_OFF; \
|
||||||
|
struct { \
|
||||||
|
char c; \
|
||||||
|
uint32_t addr; \
|
||||||
|
uint32_t size; \
|
||||||
|
uint32_t extra; \
|
||||||
|
} __attribute__((packed)) log = {'h',0,0,0}; \
|
||||||
|
write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log); \
|
||||||
|
while (1) {} \
|
||||||
|
} } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal functions.
|
* Internal functions.
|
||||||
*/
|
*/
|
||||||
@ -137,14 +163,52 @@ static spin_lock_t mem_lock = { 0 };
|
|||||||
|
|
||||||
void * __attribute__ ((malloc)) malloc(uintptr_t size) {
|
void * __attribute__ ((malloc)) malloc(uintptr_t size) {
|
||||||
spin_lock(mem_lock);
|
spin_lock(mem_lock);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
size += 8;
|
||||||
|
#endif
|
||||||
void * ret = klmalloc(size);
|
void * ret = klmalloc(size);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
if (ret) {
|
||||||
|
char * c = ret;
|
||||||
|
uintptr_t s = size-8;
|
||||||
|
memcpy(&c[size-4],&s,sizeof(uintptr_t));
|
||||||
|
s = 0xDEADBEEF;
|
||||||
|
memcpy(&c[size-8],&s,sizeof(uintptr_t));
|
||||||
|
}
|
||||||
|
struct {
|
||||||
|
char c;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t extra;
|
||||||
|
} __attribute__((packed)) log = {'m',(uint32_t)ret,size-8,0xDEADBEEF};
|
||||||
|
write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log);
|
||||||
|
#endif
|
||||||
spin_unlock(mem_lock);
|
spin_unlock(mem_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size) {
|
void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size) {
|
||||||
spin_lock(mem_lock);
|
spin_lock(mem_lock);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
size += 8;
|
||||||
|
#endif
|
||||||
void * ret = klrealloc(ptr, size);
|
void * ret = klrealloc(ptr, size);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
if (ret) {
|
||||||
|
char * c = ret;
|
||||||
|
uintptr_t s = size-8;
|
||||||
|
memcpy(&c[size-4],&s,sizeof(uintptr_t));
|
||||||
|
s = 0xDEADBEEF;
|
||||||
|
memcpy(&c[size-8],&s,sizeof(uintptr_t));
|
||||||
|
}
|
||||||
|
struct {
|
||||||
|
char c;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t extra;
|
||||||
|
} __attribute__((packed)) log = {'r',(uint32_t)ptr,size-8,(uint32_t)ret};
|
||||||
|
write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log);
|
||||||
|
#endif
|
||||||
spin_unlock(mem_lock);
|
spin_unlock(mem_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -152,13 +216,41 @@ void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size) {
|
|||||||
void * __attribute__ ((malloc)) calloc(uintptr_t nmemb, uintptr_t size) {
|
void * __attribute__ ((malloc)) calloc(uintptr_t nmemb, uintptr_t size) {
|
||||||
spin_lock(mem_lock);
|
spin_lock(mem_lock);
|
||||||
void * ret = klcalloc(nmemb, size);
|
void * ret = klcalloc(nmemb, size);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
struct {
|
||||||
|
char c;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t extra;
|
||||||
|
} __attribute__((packed)) log = {'c',(uint32_t)ret,size,nmemb};
|
||||||
|
write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log);
|
||||||
|
#endif
|
||||||
spin_unlock(mem_lock);
|
spin_unlock(mem_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * __attribute__ ((malloc)) valloc(uintptr_t size) {
|
void * __attribute__ ((malloc)) valloc(uintptr_t size) {
|
||||||
spin_lock(mem_lock);
|
spin_lock(mem_lock);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
size += 8;
|
||||||
|
#endif
|
||||||
void * ret = klvalloc(size);
|
void * ret = klvalloc(size);
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
if (ret) {
|
||||||
|
char * c = ret;
|
||||||
|
uintptr_t s = size-8;
|
||||||
|
memcpy(&c[size-4],&s,sizeof(uintptr_t));
|
||||||
|
s = 0xDEADBEEF;
|
||||||
|
memcpy(&c[size-8],&s,sizeof(uintptr_t));
|
||||||
|
}
|
||||||
|
struct {
|
||||||
|
char c;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t extra;
|
||||||
|
} __attribute__((packed)) log = {'v',(uint32_t)ret,size-8,0xDEADBEEF};
|
||||||
|
write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log);
|
||||||
|
#endif
|
||||||
spin_unlock(mem_lock);
|
spin_unlock(mem_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -166,6 +258,25 @@ void * __attribute__ ((malloc)) valloc(uintptr_t size) {
|
|||||||
void free(void * ptr) {
|
void free(void * ptr) {
|
||||||
spin_lock(mem_lock);
|
spin_lock(mem_lock);
|
||||||
if ((uintptr_t)ptr > placement_pointer) {
|
if ((uintptr_t)ptr > placement_pointer) {
|
||||||
|
#ifdef _DEBUG_MALLOC
|
||||||
|
HALT_ON(0x143c000);
|
||||||
|
IRQ_OFF;
|
||||||
|
char * tag = ptr;
|
||||||
|
uintptr_t i = 0;
|
||||||
|
uint32_t * x;
|
||||||
|
while (i < 102400) {
|
||||||
|
x = (uint32_t*)(tag + i);
|
||||||
|
if (*x == 0xDEADBEEF) break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
struct {
|
||||||
|
char c;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t extra;
|
||||||
|
} __attribute__((packed)) log = {'f',(uint32_t)ptr,x[1],x[0]};
|
||||||
|
write_fs(&_kmalloc_log, 0, sizeof(log), (uint8_t *)&log);
|
||||||
|
#endif
|
||||||
klfree(ptr);
|
klfree(ptr);
|
||||||
}
|
}
|
||||||
spin_unlock(mem_lock);
|
spin_unlock(mem_lock);
|
||||||
|
42
util/process_log.py
Normal file
42
util/process_log.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
|
addresses = {}
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
data = sys.stdin.read(13)
|
||||||
|
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)
|
||||||
|
|
||||||
|
if t == 'm':
|
||||||
|
addresses[addr] = size
|
||||||
|
elif t == 'v':
|
||||||
|
addresses[addr] = size
|
||||||
|
elif t == 'c':
|
||||||
|
addresses[addr] = 'c'
|
||||||
|
elif t == 'r':
|
||||||
|
if addr not in addresses:
|
||||||
|
print("Bad realloc: 0x%x" % addr)
|
||||||
|
else:
|
||||||
|
addresses[addr] = None
|
||||||
|
addresses[extra] = size
|
||||||
|
elif t == 'f':
|
||||||
|
if addr not in addresses:
|
||||||
|
print("Bad free detected: 0x%x" % addr)
|
||||||
|
elif addresses[addr] is None:
|
||||||
|
print("Double free detected: 0x%x" % addr)
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
addresses[addr] = None
|
||||||
|
else:
|
||||||
|
print("Garbage data detected: ", t, addr, size, extra)
|
||||||
|
break
|
||||||
|
|
Loading…
Reference in New Issue
Block a user