I know heap corruption is one of the ultimate evils of psp homebrew as we don't have the same dev tools as the official sony devs do. I assume the extra 32mb of memory they get is partially for memory error checking.
Anyway to the point, I am pretty sure my program has a heap corruption problem somewhere, however it is a large project and I am finding it _very_ difficult to find the error by eye, when using psplink my program crashes without exception causing the psp to shutoff after a few seconds.
My question is does anybody have any good tips for finding memory overflows and general heap corruption, or is there a way I could write some sort of heap debugger into my program easily (bearing in mind that my program uses a wrapper function for malloc so I can insert code in all malloc calls if need be) ?
Heap corruption
A lot of people write 'sentinel' values into their allocations, so when you wrap malloc, alloc an extra trio of dwords, one at the beginning, the allocation size, and one at the end, and write magic values in there (eg. 0xdeadbeef or 0x0badf00d). When you free the allocation, check to make sure these haven't been overwritten.
so something like (untested)
The developers' extra 32megs is usually so they can worry about making the game work in the early stages of development without having to worry about cramming it in to a tiny memory space. That problem can usually be left to the end, if necessary.
Jim
so something like (untested)
Code: Select all
void *mymalloc(size_t size)
{
char *mem;
/*you want to round size up to the next multiple of 4 to avoid alignment problems*/
size += (4-(size&3))&3;
mem = malloc(size + 12);
*(int *)mem = 0xdeadbeef;
*(size_t *)(mem+4) = size;
*(int *)(mem+size+8) = 0x0badf00d;
return mem+8;
}
void myfree(void *mptr)
{
char *mem = (char *)mptr-8;
size_t size;
assert(*(int *)mem == 0xdeadbeef);
size = *(size_t *)(mem+4);
assert(*(int *)(mem+size+8) == 0x0badf00d);
free(mem);
}
Jim
OK, thanks for all the replies. I implemented an error checker and a linked list containing allocation information (only used when compiled with debugging). I have tested it on lots of situations and it seems pretty tight, so my problem now is that the main original problem I have may not have been due to heap corruption.
I have 2 problems at the minute which I am having great trouble tracking down.
1. Certain projects just crash when memory error checking is enabled, I doubt it is todo with the code being wrong so maybe the projects rely on memory being initialized in a certain way or something.
2. I am getting seemingly random heap corruption, which I don't think is todo with over/under flows.
I doubt the root of my problem is todo with stack overflows either, is there anything else that could cause the above problems.
I have 2 problems at the minute which I am having great trouble tracking down.
1. Certain projects just crash when memory error checking is enabled, I doubt it is todo with the code being wrong so maybe the projects rely on memory being initialized in a certain way or something.
2. I am getting seemingly random heap corruption, which I don't think is todo with over/under flows.
I doubt the root of my problem is todo with stack overflows either, is there anything else that could cause the above problems.
Until you fix that, there's no reason to believe your heap isn't being corrupted. Perhaps try adding some more blank space to the beginning and end of the allocations (instead of just one dword) - perhaps you're overstepping by a larger amount.Certain projects just crash when memory error checking is enabled
Try removing parts of the program until it goes away.
Why would that be?maybe the projects rely on memory being initialized in a certain way or something.
Jim
OK, I thought it would be rude not to reply after all the help you guys have given me, so thanks.
The system I have now allocates n bytes at the beginning and end of the data where n is the byte alignment, in the 16 bytes closest to the data it contains the blocks size, alignment and then the 8 bytes closest to the data at each end contain 4 different identifiable hex strings to make it easy to see when debugging.
I also add all allocations to a linked list that contains the size, alignment and a pointer to the memory block.
Then after each memory operation memSet/memClear/memCopy/memAlloc/memFree/etc. I call a test algorithm that scans every block in the list for inconsistencies and reports an overflow or an underflow.
It did work, and found a few small errors in an old function used for finding file extensions, but frustratingly I don't think my problems were memory related anyway, I think the problem was a logical error todo with pointers in my model rendering code.
The system I have now allocates n bytes at the beginning and end of the data where n is the byte alignment, in the 16 bytes closest to the data it contains the blocks size, alignment and then the 8 bytes closest to the data at each end contain 4 different identifiable hex strings to make it easy to see when debugging.
I also add all allocations to a linked list that contains the size, alignment and a pointer to the memory block.
Then after each memory operation memSet/memClear/memCopy/memAlloc/memFree/etc. I call a test algorithm that scans every block in the list for inconsistencies and reports an overflow or an underflow.
It did work, and found a few small errors in an old function used for finding file extensions, but frustratingly I don't think my problems were memory related anyway, I think the problem was a logical error todo with pointers in my model rendering code.