■
id:isshikiさんと、valgrindは素晴らしいけどWindowsでは使えん的な話をしてて。Electric Fenceみたいなものだったらすぐできんじゃないかと思って、超やっつけで書いた↓
enum chunk_state_t {
CHUNK_FREE,
CHUNK_ALLOCATED,
};
struct chunk
{
enum chunk_state_t state;
size_t page_size;
size_t mem_size;
void *mem_addr;
void *page_addr;
};
#define PAGE_SIZE 4096
#define CHUNK_NUM 1024
static struct chunk chunks[CHUNK_NUM];
static int initialized;
static struct chunk *
find_chunk( void *p )
{
int i;
for ( i=0; i<CHUNK_NUM; i++ ) {
if ( chunks[i].state == CHUNK_ALLOCATED &&
chunks[i].mem_addr == p )
return chunks+i;
}
return NULL;
}
static struct chunk *
alloc_chunk( void )
{
int i;
for ( i=0; i<CHUNK_NUM; i++ ) {
if ( chunks[i].state == CHUNK_FREE )
return chunks+i;
}
MessageBox( NULL, "oh! memory wariatesugidayo!", "orz OTL", MB_OK );
*(char*)0 = 0;
return NULL;
}
void *
malloc( size_t sz )
{
size_t page_aligned_size;
char *page_memory;
char *mem_addr;
DWORD old_prot;
struct chunk *chunk;
page_aligned_size = (sz+(PAGE_SIZE-1))&~(PAGE_SIZE-1);
page_memory = VirtualAlloc( NULL,
page_aligned_size+PAGE_SIZE,
MEM_RESERVE, PAGE_EXECUTE_READWRITE );
VirtualAlloc( page_memory,
page_aligned_size,
MEM_COMMIT, PAGE_EXECUTE_READWRITE );
mem_addr = page_memory + page_aligned_size-sz;
chunk = alloc_chunk( );
chunk->state = CHUNK_ALLOCATED;
chunk->page_size = page_aligned_size + PAGE_SIZE;
chunk->mem_size = sz;
chunk->page_addr = page_memory;
chunk->mem_addr = mem_addr;
return mem_addr;
}
void *
realloc( void *ptr, size_t resize )
{
struct chunk *c;
void *new_ptr;
if ( ptr == NULL )
return malloc( resize );
c = find_chunk( ptr );
if ( c == NULL ) {
MessageBox( NULL, "WARNING: hennna realloc", "orz", MB_OK );
return malloc( resize );
}
if ( c->mem_size > resize )
return c->mem_addr;
new_ptr = malloc( resize );
memcpy( new_ptr, ptr, c->mem_size );
free( ptr );
return new_ptr;
}
void
free( void *ptr )
{
int i;
for ( i=0; i<CHUNK_NUM; i++ ) {
if ( chunks[i].mem_addr == ptr ) {
if ( chunks[i].state != CHUNK_ALLOCATED ) {
MessageBox( NULL, "WARNING: double free", "orz", MB_OK );
return;
}
VirtualFree( chunks[i].page_addr, chunks[i].page_size, MEM_RELEASE );
chunks[i].state = CHUNK_FREE;
return;
}
}
MessageBox( NULL, "WARNING: free not allocated memory.", "orz", MB_OK );
}int main()
{
char *p = malloc( 3 );
p[0] = 'a';
puts("0");
p[1] = 'a';
puts("1");
p[2] = 'a';
puts("2");
p[3] = 'a'; /* ここで */
puts("3");
free( p );
return 0;
}こういうプログラムを書くと、p[3] = 'a'のところで落ちます。これを一緒にリンクして、なんだかんだ。
超簡単にgdbの使い方も書いておきます。
$ gdb xxx.exe # gdbをこれで実行 > run # これでプログラムが開始 recieve SIGSEGV # (とかそんな感じのメッセージ) > bt # backtraceコマンド実行 # バックトレースがだらだらと
これでどうでしょう?