alpinestudios / oogabooga

ooga booga
Other
223 stars 247 forks source link

Heap error when testing allocator [SOLVED] #1

Closed bonmas14 closed 4 months ago

bonmas14 commented 4 months ago

Hello, i have problem when program just exits with error code when i do something with in allocated array. After some debug i've found oogabooga_run_tests() function, and after inserting it into my code that throws this error:

Testing allocator... Assertion failed in file ..\oogabooga\memory.c on line 151
Failed Condition: (u64)meta >= (u64)meta->block->start && (u64)meta < (u64)meta->block->start+meta->block->size. Message: Heap error: Pointer is not in it's metadata block. This could be heap corruption but it's more likely an internal error. That's not good.

full output:

PS C:\Users\bonmas14\projects\oogabooga> .\build\cgame.exe
Ooga booga program started
Program memory grew to 5120 kb
Program memory grew to 8256 kb
[INFO]:    Ooga booga version is 0.01.000
[VERBOSE]: d3d11 gfx_init
Program memory grew to 16448 kb
[VERBOSE]: D3D11 debug is active
[VERBOSE]: Created D3D11 device
[INFO]:    D3D11 adapter is: AMD Radeon RX 580 2048SP
[VERBOSE]: Present mode is flip discard, 3 buffers
[INFO]:    Created swap chain of size 1280x720
[VERBOSE]: Cached shaders loaded
[VERBOSE]: Shaders created
[INFO]:    D3D11 init done
[VERBOSE]: CPU has sse1: true
[VERBOSE]: CPU has sse2: true
[VERBOSE]: CPU has sse3: true
[VERBOSE]: CPU has ssse3: true
[VERBOSE]: CPU has sse41: true
[VERBOSE]: CPU has sse42: true
[VERBOSE]: CPU has avx: true
[VERBOSE]: CPU has avx2: false
[VERBOSE]: CPU has avx512: false
[VERBOSE]: Created a D3D11 image of width 16 and height 16.
1 1 3
Testing allocator... Assertion failed in file ..\oogabooga\memory.c on line 151
Failed Condition: (u64)meta >= (u64)meta->block->start && (u64)meta < (u64)meta->block->start+meta->block->size. Message: Heap error: Pointer is not in it's metadata block. This could be heap corruption but it's more likely an internal error. That's not good.
C:\Users\bonmas14\projects\oogabooga\oogabooga\os_impl_windows.c:1035: os_get_stack_trace
C:\Users\bonmas14\projects\oogabooga\oogabooga\os_interface.c:317: dump_stack_trace
C:\Users\bonmas14\projects\oogabooga\oogabooga\memory.c:360: heap_alloc
C:\Users\bonmas14\projects\oogabooga\oogabooga\memory.c:463: heap_allocator_proc
C:\Users\bonmas14\projects\oogabooga\oogabooga\base.c:100: alloc
C:\Users\bonmas14\projects\oogabooga\oogabooga\tests.c:153: test_allocator
C:\Users\bonmas14\projects\oogabooga\oogabooga\tests.c:1218: oogabooga_run_tests
C:\Users\bonmas14\projects\oogabooga\entry_danmaku_dungeons.c:110: entry
C:\Users\bonmas14\projects\oogabooga\oogabooga\oogabooga.c:383: main
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288: __scrt_common_main_seh
BaseThreadInitThunk
RtlUserThreadStart[INFO]:    Successfully initialized default audio device. Channels: 2, sample_rate: 44100, bits: 32
PS C:\Users\bonmas14\projects\oogabooga> $LASTEXITCODE
-1073741795
PS C:\Users\bonmas14\projects\oogabooga>

the problem i have with my game, is that when i dont move it works fine (bullets spawn correctly) but if before spawning any bullet (from startup) and move player, and try to spawn bullets 2 times, it drops error, to reproduce it just clone my game

steps to reproduce:

git clone https://github.com/alpinestudios/oogabooga.git
cd oogabooga
# add this c file from archive and edit build.c
.\build.bat
.\build\cgame.exe
# it should show error

this is code that produces this error:

entry_mem_test.zip

asbott commented 4 months ago

That took me a while to find, but you are corrupting the heap because of a typo on this line:

world = alloc(get_heap_allocator(), sizeof(world));

I think you meant to do sizeof(world_t), because now you're just allocating 8 bytes but then as you create an entity and write to anything beyond 8 bytes of offset you start writing to unallocated memory.

Tip: if you do #define VERY_DEBUG 1 at the top of build.c, the memory allocator will do a lot more checks and catch heap corruption earlier and let you know when it sees it. Then you can spam "alloc" everywhere you suspect it might be happening to deduce which line causes the corruption.

This time it was a bit difficult to track down because the exact line that caused the corruption was entity->sprite = sprite_get(SPRITE_player); because the struct member sprite has an offset greater than 8, surpassing the 8 bytes of memory you allocated.

I also realize the error message that was outputted is a bit misleading, I'll improve that.

bonmas14 commented 4 months ago

Thank you! I don't even understand how I didn't notice it right away. Now everything is working