Mon 23 Jan 2012 04:27:01 AM UTC, comment #2:
I just found what might be a more deterministic approach to reproducing this bug, although the stack frames starting at unit_animator::wait_for_end() (at src/unit_animation.cpp:1133) may vary for one or another reason.
It's very likely this bug is really a race condition of sorts caused by the Create Unit action in debug mode, which is why I undid the severity switch.
- Start the test scenario.
- Bring up the Preferences dialog, enable Accelerated mode and set the acceleration factor below 1x in order to slow down recruited animations (which are triggered by Create Unit)
- Choose any visible vacant hex and spawn a Blood Bat using the Create Unit action; quickly create a new unit on the same hex before the Bat's recruited animation finishes. This is rather easy to do, since the dialog remembers its last choice and Enter can be used instead of clicking n Okay.
- Repeat the previous step combined with a quick click on the target hex -- the game should crash after the second attempt, but that's not necessarily guaranteed.
The problem with this is that it might be a symptom of a different problem and not necessarily a debug-mode-specific bug. It's hard to say since the exact cause isn't clear to me yet; when I originally reproduced the bug, I wasn't creating units too quickly nor on the same hex, but they were indeed being "recruited", used to attack, and destroyed rather quickly, albeit with an animation acceleration factor of 1.7x.
|
Mon 23 Jan 2012 03:50:10 AM UTC, comment #1:
I finally managed to reproduce this (not using the provided save or case, though), and found some things. Since this is yet another display of undefined behavior, I have increased this bug's priority to Blocker, hoping it's fixed before the first 1.10 point release.
Backtrace:
Frame #2 is the first relevant point:
There's clearly a dangling pointer floating around:
Checking frame #4 and assuming I'm interpreting things right, it seems unit::get_animation() has a chance to return a dangling pointer:
There are a few instances in unit.cpp (containing the implementation of various unit class methods) where the anim_ field is used; in the few situations where the delete operator is applied on it in this file, it's either reset to NULL or replaced with a new instance of a unit_animation object. Thus, it's possible some code elsewhere is getting access to this pointer and deleting the object referenced.
|
Fri 04 Nov 2011 08:32:32 PM UTC, original submission:
While testing the Dwarvish Witness line's improved leadership animations, I encountered this.
I have attached a savefile that can be used to reproduce this.
To reproduce:
1. Download the savefile and put it in your saves directory
2. Load the savefile
3. Go into debug mode
4. Keep attacking the Dwarvish Thunderguard in the middle with Ulfserkers... spawn more in the same spot and keep attacking as needed
5. The game should crash after so many Ulfserkers have died
Error:
Program received signal SIGSEGV, Segmentation fault.
0x00000000006baf9e in std::vector<animated<unit_frame>::frame, std::allocator<animated<unit_frame>::frame> >::end (this=0x206c6c65772068a6)
at /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_vector.h:454
454 { return const_iterator(this->_M_impl._M_finish); }
Backtrace:
#0 0x00000000006baf9e in std::vector<animated<unit_frame>::frame, std::allocator<animated<unit_frame>::frame> >::end (this=0x206c6c65772068a6)
at /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_vector.h:454
#1 0x000000000086d376 in std::vector<animated<unit_frame>::frame, std::allocator<animated<unit_frame>::frame> >::empty (this=0x206c6c65772068a6)
at /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_vector.h:583
#2 0x000000000086c207 in animated<unit_frame, void_value<unit_frame> >::animation_finished_potential (this=0x206c6c6577206896) at src/animated.i:180
#3 0x00000000006e5f46 in unit_animation::animation_finished_potential (this=0x206c6c657720676e) at src/unit_animation.cpp:798
#4 0x00000000006e7c24 in unit_animator::wait_for_end (this=0x7fffffff9050) at src/unit_animation.cpp:1132
#5 0x0000000000a9754d in unit_display::unit_recruited (loc=..., leader_loc=...) at src/unit_display.cpp:459
#6 0x0000000000a3207d in events::menu_handler::create_unit (this=0x7fffffffb580, mousehandler=...) at src/menu_events.cpp:1607
#7 0x0000000000614964 in playsingle_controller::create_unit (this=0x7fffffffb3c0) at src/playsingle_controller.cpp:168
#8 0x0000000000cb3b15 in hotkey::command_executor::execute_command (this=0x7fffffffb3c0, command=hotkey::HOTKEY_CREATE_UNIT) at src/hotkeys.cpp:1014
#9 0x0000000000a7c15e in play_controller::execute_command (this=0x7fffffffb3c0, command=hotkey::HOTKEY_CREATE_UNIT, index=0) at src/play_controller.cpp:786
#10 0x0000000000cb40b1 in hotkey::execute_command (disp=..., command=hotkey::HOTKEY_CREATE_UNIT, executor=0x7fffffffb3c0, index=0) at src/hotkeys.cpp:1151
#11 0x0000000000cb4e50 in hotkey::command_executor::show_menu (this=0x7fffffffb3c0, items_arg=std::vector of length 8, capacity 24 = {...}, xloc=609, yloc=373, context_menu=true, gui=...)
at src/hotkeys.cpp:1259
#12 0x0000000000a7ebe8 in play_controller::show_menu (this=0x7fffffffb3c0, items_arg=std::vector of length 24, capacity 24 = {...}, xloc=609, yloc=373, context_menu=true)
at src/play_controller.cpp:1201
#13 0x000000000087e9ca in controller_base::handle_event (this=0x7fffffffb3c0, event=...) at src/controller_base.cpp:94
#14 0x0000000000caa166 in events::pump () at src/events.cpp:380
#15 0x000000000087f114 in controller_base::play_slice (this=0x7fffffffb3c0, is_delay_enabled=true) at src/controller_base.cpp:197
#16 0x0000000000618147 in playsingle_controller::play_human_turn (this=0x7fffffffb3c0) at src/playsingle_controller.cpp:711
#17 0x00000000006179e6 in playsingle_controller::play_side (this=0x7fffffffb3c0, team_index=1, save=false) at src/playsingle_controller.cpp:636
#18 0x0000000000617616 in playsingle_controller::play_turn (this=0x7fffffffb3c0, save=false) at src/playsingle_controller.cpp:590
#19 0x0000000000615e80 in playsingle_controller::play_scenario (this=0x7fffffffb3c0, story=..., skip_replay=false) at src/playsingle_controller.cpp:391
#20 0x0000000000608465 in playsingle_scenario (game_config=..., level=0x163d488, disp=..., state_of_game=..., story=..., skip_replay=false, end_level=...) at src/playcampaign.cpp:130
#21 0x000000000060ad2d in play_game (disp=..., gamestate=..., game_config=..., io_type=IO_NONE, skip_replay=false) at src/playcampaign.cpp:365
#22 0x000000000048b000 in game_controller::launch_game (this=0x163d220, reload=game_controller_abstract::NO_RELOAD_DATA) at src/game_controller.cpp:1267
#23 0x0000000000424696 in do_gameloop (argc=1, argv=0x7fffffffdc28) at src/game.cpp:573
#24 0x0000000000424b93 in main (argc=1, argv=0x7fffffffdc28) at src/game.cpp:627
|