New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory access violation / corrupted heap in EffectManager destructor causes game to crash #1360

Closed
henrik-m opened this Issue Feb 16, 2015 · 17 comments

Comments

Projects
None yet
3 participants
@henrik-m
Contributor

henrik-m commented Feb 16, 2015

Running the setup from #1358, starting in "Asylum Living Quarters" and working my way up north with my horde of slave monsters, the game crashed when I entered the map exit point in the north west of the "Marshlands" map. This is the stacktrace:

flare-engine.exe!std::allocator<std::_Container_proxy>::deallocate(std::_Container_proxy * _Ptr, unsigned int __formal) Line 573 C++
flare-engine.exe!std::_Wrap_alloc<std::allocator<std::_Container_proxy> >::deallocate(std::_Container_proxy * _Ptr, unsigned int _Count) Line 859 C++
flare-engine.exe!std::_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >::_Free_proxy() Line 636 C++
flare-engine.exe!std::_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >::~_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >() Line 609 C++
flare-engine.exe!std::vector<int,std::allocator<int> >::~vector<int,std::allocator<int> >() Line 946 C++
flare-engine.exe!EffectManager::~EffectManager() Line 43 C++
flare-engine.exe!StatBlock::~StatBlock() Line 639 C++
flare-engine.exe!Entity::~Entity() Line 460 C++
flare-engine.exe!Enemy::~Enemy() Line 187 C++
[External Code]
flare-engine.exe!EnemyManager::handleNewMap() Line 87 C++
flare-engine.exe!GameStatePlay::checkTeleport() Line 290 C++
flare-engine.exe!GameStatePlay::logic() Line 867 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++
flare-engine.exe!main(int argc, char * * argv) Line 140 C

It seems like the program crashed on trying to delete the effect_list-Vector in EffectManager.

If it is any help: I climbed a few levels on my way and had unlocked Werewyvern 4, but was not in wyvern form when I left the map. Here is a screenshot from the exact moment of the crash:
image

@dorkster dorkster added the bug label Feb 16, 2015

@dorkster dorkster added this to the Pre-1.0 milestone Feb 16, 2015

@dorkster

This comment has been minimized.

Show comment
Hide comment
@dorkster

dorkster Feb 16, 2015

Collaborator

I happened to get a different crash in the same area, only it didn't happen during map transition. Here's the backtrace:

(gdb) backtrace 
#0  0x00007ffff67659db in __lll_lock_wait_private () from /usr/lib/libc.so.6
#1  0x00007ffff66eb80c in malloc () from /usr/lib/libc.so.6
#2  0x00007ffff7de806f in _dl_map_object_deps () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7dee4cf in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dea0a4 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7dede53 in _dl_open () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff678e1fd in do_dlopen () from /usr/lib/libc.so.6
#7  0x00007ffff7dea0a4 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#8  0x00007ffff678e28f in dlerror_run () from /usr/lib/libc.so.6
#9  0x00007ffff678e301 in __libc_dlopen_mode () from /usr/lib/libc.so.6
#10 0x00007ffff6766255 in init () from /usr/lib/libc.so.6
#11 0x00007ffff78c8e3b in __pthread_once_slow () from /usr/lib/libpthread.so.0
#12 0x00007ffff676636c in backtrace () from /usr/lib/libc.so.6
#13 0x00007ffff6690b25 in backtrace_and_maps () from /usr/lib/libc.so.6
#14 0x00007ffff66e298e in __libc_message () from /usr/lib/libc.so.6
#15 0x00007ffff66e7dee in malloc_printerr () from /usr/lib/libc.so.6
#16 0x00007ffff66e8de9 in _int_free () from /usr/lib/libc.so.6
#17 0x00000000004e4ecb in __gnu_cxx::new_allocator<Point>::deallocate (this=0x1b19ca0, __p=0x10155a0) at /usr/include/c++/4.9.2/ext/new_allocator.h:110
#18 0x00000000004e4311 in __gnu_cxx::__alloc_traits<std::allocator<Point> >::deallocate (__a=..., __p=0x10155a0, __n=64) at /usr/include/c++/4.9.2/ext/alloc_traits.h:185
#19 0x00000000004e2fed in std::_Vector_base<Point, std::allocator<Point> >::_M_deallocate (this=0x1b19ca0, __p=0x10155a0, __n=64)
    at /usr/include/c++/4.9.2/bits/stl_vector.h:178
#20 0x00000000004e1c32 in std::_Vector_base<Point, std::allocator<Point> >::~_Vector_base (this=0x1b19ca0, __in_chrg=<optimized out>)
    at /usr/include/c++/4.9.2/bits/stl_vector.h:160
#21 0x00000000004e10ce in std::vector<Point, std::allocator<Point> >::~vector (this=0x1b19ca0, __in_chrg=<optimized out>) at /usr/include/c++/4.9.2/bits/stl_vector.h:425
#22 0x00000000004e1017 in Animation::~Animation (this=0x1b19c60, __in_chrg=<optimized out>) at /home/justin/Projects/flare-engine/src/Animation.h:43
#23 0x00000000004dfe77 in Entity::setAnimation (this=0x1faa830, animationName="cast") at /home/justin/Projects/flare-engine/src/Entity.cpp:449
#24 0x000000000050870b in BehaviorStandard::updateState (this=0x1442e30) at /home/justin/Projects/flare-engine/src/BehaviorStandard.cpp:557
#25 0x00000000005068a0 in BehaviorStandard::logic (this=0x1442e30) at /home/justin/Projects/flare-engine/src/BehaviorStandard.cpp:57
#26 0x000000000051281d in Enemy::logic (this=0x1faa830) at /home/justin/Projects/flare-engine/src/Enemy.cpp:108
#27 0x0000000000518547 in EnemyManager::logic (this=0xd87160) at /home/justin/Projects/flare-engine/src/EnemyManager.cpp:339
#28 0x000000000054a65f in GameStatePlay::logic (this=0xd42740) at /home/justin/Projects/flare-engine/src/GameStatePlay.cpp:848
#29 0x00000000005526a0 in GameSwitcher::logic (this=0xc24a10) at /home/justin/Projects/flare-engine/src/GameSwitcher.cpp:115
#30 0x00000000006193f2 in mainLoop (debug_event=false) at /home/justin/Projects/flare-engine/src/main.cpp:160
#31 0x0000000000619c3a in main (argc=1, argv=0x7fffffffe828) at /home/justin/Projects/flare-engine/src/main.cpp:297

I'm suspecting this might have something to do with the Animation class.

Collaborator

dorkster commented Feb 16, 2015

I happened to get a different crash in the same area, only it didn't happen during map transition. Here's the backtrace:

(gdb) backtrace 
#0  0x00007ffff67659db in __lll_lock_wait_private () from /usr/lib/libc.so.6
#1  0x00007ffff66eb80c in malloc () from /usr/lib/libc.so.6
#2  0x00007ffff7de806f in _dl_map_object_deps () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7dee4cf in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dea0a4 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7dede53 in _dl_open () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff678e1fd in do_dlopen () from /usr/lib/libc.so.6
#7  0x00007ffff7dea0a4 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#8  0x00007ffff678e28f in dlerror_run () from /usr/lib/libc.so.6
#9  0x00007ffff678e301 in __libc_dlopen_mode () from /usr/lib/libc.so.6
#10 0x00007ffff6766255 in init () from /usr/lib/libc.so.6
#11 0x00007ffff78c8e3b in __pthread_once_slow () from /usr/lib/libpthread.so.0
#12 0x00007ffff676636c in backtrace () from /usr/lib/libc.so.6
#13 0x00007ffff6690b25 in backtrace_and_maps () from /usr/lib/libc.so.6
#14 0x00007ffff66e298e in __libc_message () from /usr/lib/libc.so.6
#15 0x00007ffff66e7dee in malloc_printerr () from /usr/lib/libc.so.6
#16 0x00007ffff66e8de9 in _int_free () from /usr/lib/libc.so.6
#17 0x00000000004e4ecb in __gnu_cxx::new_allocator<Point>::deallocate (this=0x1b19ca0, __p=0x10155a0) at /usr/include/c++/4.9.2/ext/new_allocator.h:110
#18 0x00000000004e4311 in __gnu_cxx::__alloc_traits<std::allocator<Point> >::deallocate (__a=..., __p=0x10155a0, __n=64) at /usr/include/c++/4.9.2/ext/alloc_traits.h:185
#19 0x00000000004e2fed in std::_Vector_base<Point, std::allocator<Point> >::_M_deallocate (this=0x1b19ca0, __p=0x10155a0, __n=64)
    at /usr/include/c++/4.9.2/bits/stl_vector.h:178
#20 0x00000000004e1c32 in std::_Vector_base<Point, std::allocator<Point> >::~_Vector_base (this=0x1b19ca0, __in_chrg=<optimized out>)
    at /usr/include/c++/4.9.2/bits/stl_vector.h:160
#21 0x00000000004e10ce in std::vector<Point, std::allocator<Point> >::~vector (this=0x1b19ca0, __in_chrg=<optimized out>) at /usr/include/c++/4.9.2/bits/stl_vector.h:425
#22 0x00000000004e1017 in Animation::~Animation (this=0x1b19c60, __in_chrg=<optimized out>) at /home/justin/Projects/flare-engine/src/Animation.h:43
#23 0x00000000004dfe77 in Entity::setAnimation (this=0x1faa830, animationName="cast") at /home/justin/Projects/flare-engine/src/Entity.cpp:449
#24 0x000000000050870b in BehaviorStandard::updateState (this=0x1442e30) at /home/justin/Projects/flare-engine/src/BehaviorStandard.cpp:557
#25 0x00000000005068a0 in BehaviorStandard::logic (this=0x1442e30) at /home/justin/Projects/flare-engine/src/BehaviorStandard.cpp:57
#26 0x000000000051281d in Enemy::logic (this=0x1faa830) at /home/justin/Projects/flare-engine/src/Enemy.cpp:108
#27 0x0000000000518547 in EnemyManager::logic (this=0xd87160) at /home/justin/Projects/flare-engine/src/EnemyManager.cpp:339
#28 0x000000000054a65f in GameStatePlay::logic (this=0xd42740) at /home/justin/Projects/flare-engine/src/GameStatePlay.cpp:848
#29 0x00000000005526a0 in GameSwitcher::logic (this=0xc24a10) at /home/justin/Projects/flare-engine/src/GameSwitcher.cpp:115
#30 0x00000000006193f2 in mainLoop (debug_event=false) at /home/justin/Projects/flare-engine/src/main.cpp:160
#31 0x0000000000619c3a in main (argc=1, argv=0x7fffffffe828) at /home/justin/Projects/flare-engine/src/main.cpp:297

I'm suspecting this might have something to do with the Animation class.

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 16, 2015

Collaborator

Maybe related to this ? #532 We didn't find the reason...

Collaborator

igorko commented Feb 16, 2015

Maybe related to this ? #532 We didn't find the reason...

@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 17, 2015

Contributor

Got another crash on map transition at the same spot with a similar (but not identical) stacktrace. Was running an SDL1-build now, but for this error that is probably irrelevant.

Stacktrace:

msvcr120d.dll!operator delete(void *) Unknown
flare-engine.exe!std::allocator<std::_Container_proxy>::deallocate(std::_Container_proxy * _Ptr, unsigned int __formal) Line 573 C++
flare-engine.exe!std::_Wrap_alloc<std::allocator<std::_Container_proxy> >::deallocate(std::_Container_proxy * _Ptr, unsigned int _Count) Line 859 C++
flare-engine.exe!std::_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >::_Free_proxy() Line 636 C++
flare-engine.exe!std::_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >::~_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >() Line 609 C++
flare-engine.exe!std::vector<int,std::allocator<int> >::~vector<int,std::allocator<int> >() Line 946 C++
flare-engine.exe!StatBlock::~StatBlock() Line 639 C++
flare-engine.exe!Entity::~Entity() Line 460 C++
flare-engine.exe!Enemy::~Enemy() Line 187 C++
[External Code]
flare-engine.exe!EnemyManager::handleNewMap() Line 87 C++
flare-engine.exe!GameStatePlay::checkTeleport() Line 295 C++
flare-engine.exe!GameStatePlay::logic() Line 872 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++

Heap corruption on deleting a vector class member of StatBlock, so it seems.

Screenshot:
image

Contributor

henrik-m commented Feb 17, 2015

Got another crash on map transition at the same spot with a similar (but not identical) stacktrace. Was running an SDL1-build now, but for this error that is probably irrelevant.

Stacktrace:

msvcr120d.dll!operator delete(void *) Unknown
flare-engine.exe!std::allocator<std::_Container_proxy>::deallocate(std::_Container_proxy * _Ptr, unsigned int __formal) Line 573 C++
flare-engine.exe!std::_Wrap_alloc<std::allocator<std::_Container_proxy> >::deallocate(std::_Container_proxy * _Ptr, unsigned int _Count) Line 859 C++
flare-engine.exe!std::_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >::_Free_proxy() Line 636 C++
flare-engine.exe!std::_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >::~_Vector_alloc<0,std::_Vec_base_types<int,std::allocator<int> > >() Line 609 C++
flare-engine.exe!std::vector<int,std::allocator<int> >::~vector<int,std::allocator<int> >() Line 946 C++
flare-engine.exe!StatBlock::~StatBlock() Line 639 C++
flare-engine.exe!Entity::~Entity() Line 460 C++
flare-engine.exe!Enemy::~Enemy() Line 187 C++
[External Code]
flare-engine.exe!EnemyManager::handleNewMap() Line 87 C++
flare-engine.exe!GameStatePlay::checkTeleport() Line 295 C++
flare-engine.exe!GameStatePlay::logic() Line 872 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++

Heap corruption on deleting a vector class member of StatBlock, so it seems.

Screenshot:
image

@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 17, 2015

Contributor

Another one. And in EnemyManager::handleNewMap() again.

Stacktrace

msvcr120d.dll!operator delete(void *) Unknown
flare-engine.exe!Enemy::`scalar deleting destructor'(unsigned int) C++
flare-engine.exe!EnemyManager::handleNewMap() Line 87 C++
flare-engine.exe!GameStatePlay::checkTeleport() Line 295 C++
flare-engine.exe!GameStatePlay::logic() Line 872 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++

Screenshot
image

Contributor

henrik-m commented Feb 17, 2015

Another one. And in EnemyManager::handleNewMap() again.

Stacktrace

msvcr120d.dll!operator delete(void *) Unknown
flare-engine.exe!Enemy::`scalar deleting destructor'(unsigned int) C++
flare-engine.exe!EnemyManager::handleNewMap() Line 87 C++
flare-engine.exe!GameStatePlay::checkTeleport() Line 295 C++
flare-engine.exe!GameStatePlay::logic() Line 872 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++

Screenshot
image

@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 17, 2015

Contributor

This time it happened not upon leaving the map, but when I was transforming back from ghost form.

msvcr120d.dll!operator delete(void *) Unknown
flare-engine.exe!std::allocator<std::_Container_proxy>::deallocate(std::_Container_proxy * _Ptr, unsigned int __formal) Line 573 C++
flare-engine.exe!std::_String_alloc<0,std::_String_base_types<char,std::allocator<char> > >::_Free_proxy() Line 678 C++
flare-engine.exe!std::_String_alloc<0,std::_String_base_types<char,std::allocator<char> > >::~_String_alloc<0,std::_String_base_types<char,std::allocator<char> > >() Line 651 C++
flare-engine.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() Line 992 C++
flare-engine.exe!Effect::~Effect() Line 71 C++
[External Code]
flare-engine.exe!EffectManager::~EffectManager() Line 43 C++
flare-engine.exe!StatBlock::~StatBlock() Line 639 C++
[External Code]
flare-engine.exe!Avatar::untransform() Line 856 C++
flare-engine.exe!Avatar::checkTransform() Line 870 C++
flare-engine.exe!GameStatePlay::logic() Line 889 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++

image

Contributor

henrik-m commented Feb 17, 2015

This time it happened not upon leaving the map, but when I was transforming back from ghost form.

msvcr120d.dll!operator delete(void *) Unknown
flare-engine.exe!std::allocator<std::_Container_proxy>::deallocate(std::_Container_proxy * _Ptr, unsigned int __formal) Line 573 C++
flare-engine.exe!std::_String_alloc<0,std::_String_base_types<char,std::allocator<char> > >::_Free_proxy() Line 678 C++
flare-engine.exe!std::_String_alloc<0,std::_String_base_types<char,std::allocator<char> > >::~_String_alloc<0,std::_String_base_types<char,std::allocator<char> > >() Line 651 C++
flare-engine.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() Line 992 C++
flare-engine.exe!Effect::~Effect() Line 71 C++
[External Code]
flare-engine.exe!EffectManager::~EffectManager() Line 43 C++
flare-engine.exe!StatBlock::~StatBlock() Line 639 C++
[External Code]
flare-engine.exe!Avatar::untransform() Line 856 C++
flare-engine.exe!Avatar::checkTransform() Line 870 C++
flare-engine.exe!GameStatePlay::logic() Line 889 C++
flare-engine.exe!GameSwitcher::logic() Line 115 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 297 C++

image

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 17, 2015

Collaborator

Before last stacktrace, I thought problem is in map refactoring (because issue was happening when unloading map, for me when exiting the game, so unloading map too). Now I have no idea...

Collaborator

igorko commented Feb 17, 2015

Before last stacktrace, I thought problem is in map refactoring (because issue was happening when unloading map, for me when exiting the game, so unloading map too). Now I have no idea...

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 17, 2015

Collaborator

@henrik-m Can you try e.g. Aplication Verifier (from Windows Kit). I have read that it is able to detect memory corruptions in applications.

Collaborator

igorko commented Feb 17, 2015

@henrik-m Can you try e.g. Aplication Verifier (from Windows Kit). I have read that it is able to detect memory corruptions in applications.

@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 17, 2015

Contributor

@igorko I'll give it a try

Contributor

henrik-m commented Feb 17, 2015

@igorko I'll give it a try

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 18, 2015

Collaborator

I suppose it's something with animations, we had issue with it but hard to reproducable (#532)...
EffectManager::~EffectManager() deletes animation pointers, frequent in logs.
EnemyManager::handleNewMap() deletes enemies, which also includes animations...
Avatar::untransform() one of main uses is to change animation...
I think the problem is that we have getAnimation() and getAnimationSet() methods which return pointers...so we can get double freeing somewhere...Maybe for testing purposes we could replace return values with shared_pointers (in branch?) and see what we will get...

Collaborator

igorko commented Feb 18, 2015

I suppose it's something with animations, we had issue with it but hard to reproducable (#532)...
EffectManager::~EffectManager() deletes animation pointers, frequent in logs.
EnemyManager::handleNewMap() deletes enemies, which also includes animations...
Avatar::untransform() one of main uses is to change animation...
I think the problem is that we have getAnimation() and getAnimationSet() methods which return pointers...so we can get double freeing somewhere...Maybe for testing purposes we could replace return values with shared_pointers (in branch?) and see what we will get...

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 18, 2015

Collaborator

Next time you will get this issue, please check log. Maybe we fail to create enemy etc, so as result tryremove corrupted resources...

Collaborator

igorko commented Feb 18, 2015

Next time you will get this issue, please check log. Maybe we fail to create enemy etc, so as result tryremove corrupted resources...

@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 18, 2015

Contributor

I got the crash with Application Verifier now. Had to compile flare on x64 because of all those guards put in place by AV. SDL has not enough memory left to create textures on Win32. Process memory consumption is beyond 1GB. FPS around 0 during battle. ^^

It happened on transforming back from ghost form again. Here you go:

Application Verifier Output

First-chance exception at 0x0000000140113983 in flare-engine.exe: 0xC0000005: Access violation writing location 0x000000009743AFA0.

=======================================
VERIFIER STOP 0000000000000013: pid 0x1DF0: First chance access violation for current stack trace. 

    000000009743AFA0 : Invalid address causing the exception.
    0000000140113983 : Code address executing the invalid access.
    00000000002DF070 : Exception record.
    00000000002DEB80 : Context record.


=======================================
This verifier stop is continuable.
After debugging it use `go' to continue.

=======================================

flare-engine.exe has triggered a breakpoint.

Disassembly

So you have something to go with the reported code address: https://db.tt/WagScmCe
I've included the complete disassembly of removeFromSummons to be on the safe side, just search for "0000000140113983" to get to the breakpoint address. It's more readable than you would expect because Visual Studio inserts the corresponding C++ lines of code.

Stacktrace

flare-engine.exe!StatBlock::removeFromSummons() Line 739 C++
flare-engine.exe!StatBlock::~StatBlock() Line 638 C++
[External Code]
flare-engine.exe!Avatar::untransform() Line 856 C++
flare-engine.exe!Avatar::checkTransform() Line 870 C++
flare-engine.exe!GameStatePlay::logic() Line 889 C++
flare-engine.exe!GameSwitcher::logic() Line 118 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 299 C++

Code File Breakpoint

image

Flare Engine Console Log

A copy of all console output during the game session from start to crash: https://db.tt/Ff9NVJn0

Game Screenshot

I just entered the map. I've had a few summoned creatures with me but I guess they got killed before I reached the exit point of the previous map. Maybe just as I reached it? Could that be a possible crash cause?
image

After Action Report

Started noname-mod with level 50 char savegame. Spawned in "Journeys End" map, summoned a Minotaur 5, 3x Goblin 5, 1x Ghost 5 and 2x Wyvern 5 and worked my way down south reverse through the battlefields. My monsters got their asses kicked, at first by the boss enemies in "Death Valley", and in the next map by the sheer number of enemies. They kept dying and I resummoned them as fast as I could while running across the map. Then got pinned down by a horde of melee enemies at the edge of the map. Used ghost transform to escape through the mountain wall and managed to reach the next map. Would have been fun had the game not been at 0 fps most of the time. ^^
Hit "1" to untransform --> crash

Build Configuration

flare-engine SDL 1.2 x64
Windows 7 x64

OK, can't think of any more context information. I hope you can put this to use.

Contributor

henrik-m commented Feb 18, 2015

I got the crash with Application Verifier now. Had to compile flare on x64 because of all those guards put in place by AV. SDL has not enough memory left to create textures on Win32. Process memory consumption is beyond 1GB. FPS around 0 during battle. ^^

It happened on transforming back from ghost form again. Here you go:

Application Verifier Output

First-chance exception at 0x0000000140113983 in flare-engine.exe: 0xC0000005: Access violation writing location 0x000000009743AFA0.

=======================================
VERIFIER STOP 0000000000000013: pid 0x1DF0: First chance access violation for current stack trace. 

    000000009743AFA0 : Invalid address causing the exception.
    0000000140113983 : Code address executing the invalid access.
    00000000002DF070 : Exception record.
    00000000002DEB80 : Context record.


=======================================
This verifier stop is continuable.
After debugging it use `go' to continue.

=======================================

flare-engine.exe has triggered a breakpoint.

Disassembly

So you have something to go with the reported code address: https://db.tt/WagScmCe
I've included the complete disassembly of removeFromSummons to be on the safe side, just search for "0000000140113983" to get to the breakpoint address. It's more readable than you would expect because Visual Studio inserts the corresponding C++ lines of code.

Stacktrace

flare-engine.exe!StatBlock::removeFromSummons() Line 739 C++
flare-engine.exe!StatBlock::~StatBlock() Line 638 C++
[External Code]
flare-engine.exe!Avatar::untransform() Line 856 C++
flare-engine.exe!Avatar::checkTransform() Line 870 C++
flare-engine.exe!GameStatePlay::logic() Line 889 C++
flare-engine.exe!GameSwitcher::logic() Line 118 C++
flare-engine.exe!mainLoop(bool debug_event) Line 161 C++
flare-engine.exe!SDL_main(int argc, char * * argv) Line 299 C++

Code File Breakpoint

image

Flare Engine Console Log

A copy of all console output during the game session from start to crash: https://db.tt/Ff9NVJn0

Game Screenshot

I just entered the map. I've had a few summoned creatures with me but I guess they got killed before I reached the exit point of the previous map. Maybe just as I reached it? Could that be a possible crash cause?
image

After Action Report

Started noname-mod with level 50 char savegame. Spawned in "Journeys End" map, summoned a Minotaur 5, 3x Goblin 5, 1x Ghost 5 and 2x Wyvern 5 and worked my way down south reverse through the battlefields. My monsters got their asses kicked, at first by the boss enemies in "Death Valley", and in the next map by the sheer number of enemies. They kept dying and I resummoned them as fast as I could while running across the map. Then got pinned down by a horde of melee enemies at the edge of the map. Used ghost transform to escape through the mountain wall and managed to reach the next map. Would have been fun had the game not been at 0 fps most of the time. ^^
Hit "1" to untransform --> crash

Build Configuration

flare-engine SDL 1.2 x64
Windows 7 x64

OK, can't think of any more context information. I hope you can put this to use.

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 18, 2015

Collaborator

Another idea, not to use shared pointers, but set all pointers which are deleted to NULL. , even in destructors.And hope we do not miss NULL checks... Well, if we would miss NULL checks, issue would be less random, and stacktrace would be similar in all cases...

Idea: As some pointers can be accessed/transferred between classes, they can be dereferenced, when already destroyed in different class . E.g. moving from map to map can be such case when some data was destroyed, but some still present in memory(with links to destroyed data) . We have a lot of code where pointers are public members, or public function returns pointer.This is a real evil in OOP programming.

Collaborator

igorko commented Feb 18, 2015

Another idea, not to use shared pointers, but set all pointers which are deleted to NULL. , even in destructors.And hope we do not miss NULL checks... Well, if we would miss NULL checks, issue would be less random, and stacktrace would be similar in all cases...

Idea: As some pointers can be accessed/transferred between classes, they can be dereferenced, when already destroyed in different class . E.g. moving from map to map can be such case when some data was destroyed, but some still present in memory(with links to destroyed data) . We have a lot of code where pointers are public members, or public function returns pointer.This is a real evil in OOP programming.

@dorkster

This comment has been minimized.

Show comment
Hide comment
@dorkster

dorkster Feb 18, 2015

Collaborator

This is starting to sound like it's related to #1176. I don't think my "fix" was satisfactory.

Collaborator

dorkster commented Feb 18, 2015

This is starting to sound like it's related to #1176. I don't think my "fix" was satisfactory.

@igorko

This comment has been minimized.

Show comment
Hide comment
@igorko

igorko Feb 18, 2015

Collaborator

Possible condition for bug(if we will take in account that its reproduced on noname mod, so using summoned allies).We change map when some enemy is killed in the same time. So enemy is destroyed by ally and by map transition. As a result - corrupted pointer to enemy/enemy stats.

Collaborator

igorko commented Feb 18, 2015

Possible condition for bug(if we will take in account that its reproduced on noname mod, so using summoned allies).We change map when some enemy is killed in the same time. So enemy is destroyed by ally and by map transition. As a result - corrupted pointer to enemy/enemy stats.

@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 18, 2015

Contributor

I've examined the local variables at my last breakpoint and the memory they point at. It's the hero's StatBlock that gets destroyed here (not surprising, happening at "delete hero_stats").

summons.empty() returns false, because summons.begin() != summons.end(). See this annotated code:
image

I bet those crashed wouldn't be happening If I weren't summoning creatures all the time. The StatBlock-destructor-crashes in EnemyManager could be linked to the Ghost Ally, who summons creatures himself. In fact, I didn't see this type of crash before I had a bunch of minions.

Is there code somewhere (EnemyManager?) that deletes StatBlock-Pointers of dead enemies and doesn't differentiate between summoned (allied) and "normal" enemy creatures?

Contributor

henrik-m commented Feb 18, 2015

I've examined the local variables at my last breakpoint and the memory they point at. It's the hero's StatBlock that gets destroyed here (not surprising, happening at "delete hero_stats").

summons.empty() returns false, because summons.begin() != summons.end(). See this annotated code:
image

I bet those crashed wouldn't be happening If I weren't summoning creatures all the time. The StatBlock-destructor-crashes in EnemyManager could be linked to the Ghost Ally, who summons creatures himself. In fact, I didn't see this type of crash before I had a bunch of minions.

Is there code somewhere (EnemyManager?) that deletes StatBlock-Pointers of dead enemies and doesn't differentiate between summoned (allied) and "normal" enemy creatures?

@dorkster

This comment has been minimized.

Show comment
Hide comment
@dorkster

dorkster Feb 19, 2015

Collaborator

I just pushed a few commits that fixed some bugs with summons and transformation. I think they might have fixed these crashes.

The problems were:

  1. If a summoned creature summoned creatures of their own (like the Ghost ally), they would still be alive after their summoner died. This also resulted in them still pointing to their dead summoner.
  2. When transforming, we create a copy of the hero's StatBlock (aka hero_stats). When StatBlocks are deleted, we try to remove summons. Unfortunately, this would happen when untransforming, where hero_stats gets deleted. This caused a crash, but I'm not entirely sure about the details of it.
Collaborator

dorkster commented Feb 19, 2015

I just pushed a few commits that fixed some bugs with summons and transformation. I think they might have fixed these crashes.

The problems were:

  1. If a summoned creature summoned creatures of their own (like the Ghost ally), they would still be alive after their summoner died. This also resulted in them still pointing to their dead summoner.
  2. When transforming, we create a copy of the hero's StatBlock (aka hero_stats). When StatBlocks are deleted, we try to remove summons. Unfortunately, this would happen when untransforming, where hero_stats gets deleted. This caused a crash, but I'm not entirely sure about the details of it.
@henrik-m

This comment has been minimized.

Show comment
Hide comment
@henrik-m

henrik-m Feb 19, 2015

Contributor

Looks good to me. Played around a bit with Application Verifier running (enduring a really horrible lag...) using my usual game crashing tricks ^^ and nothing happened from start to finish. Not even the heap corruption exception AV loved to throw when I was exiting the game (which was not happening/was invisible without AV).

I cannot guarantee anything on this type of bug but I suppose we can always reopen the issue if it should happen again. Great work, @dorkster !

Contributor

henrik-m commented Feb 19, 2015

Looks good to me. Played around a bit with Application Verifier running (enduring a really horrible lag...) using my usual game crashing tricks ^^ and nothing happened from start to finish. Not even the heap corruption exception AV loved to throw when I was exiting the game (which was not happening/was invisible without AV).

I cannot guarantee anything on this type of bug but I suppose we can always reopen the issue if it should happen again. Great work, @dorkster !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment