pioneerspacesim/pioneer — Issue #1019: BB advert onDelete event can be run after the game has exit
Author: Brianetta
Created: 2012-02-25 18:22:50+00:00
State: open
Labels: Crash or hang

My problem is trying to save a Character sheet in an onDelete function. Part of the save routine involves getting the Game.player:GetDockedWith(). Normally, if the player isn't docked, that method returns nil. However, if it's run outside of a game context, it segfaults, deeply. Here's the backtrace:

```
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff65e8263 in std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0x00007ffff65e8263 in std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x00007ffff6cb9152 in sigc::internal::signal_impl::insert(std::_List_iterator, sigc::slot_base const&) () from /usr/lib/libsigc-2.0.so.0
#2 0x00007ffff6cb91c0 in sigc::internal::signal_impl::connect(sigc::slot_base const&) () from /usr/lib/libsigc-2.0.so.0
#3 0x00007ffff6cb9384 in sigc::signal_base::connect(sigc::slot_base const&) ()
from /usr/lib/libsigc-2.0.so.0
#4 0x000000000049ae04 in connect (slot_=..., this=)
at /usr/include/sigc++-2.0/sigc++/signal.h:2661
#5 LuaObjectBase::Push (lo=0x10ffcb0, wantdelete=)
at LuaObject.cpp:422
#6 0x00000000004a358d in PushToLua (o=0x536e5f0) at LuaObject.h:220
#7 l_ship_get_docked_with (l=) at LuaShip.cpp:807
#8 0x00000000005b441c in luaD_precall (L=0x10569f0, func=,
nresults=1) at ldo.c:319
#9 0x00000000005c3928 in luaV_execute (L=0x10569f0, nexeccalls=2) at lvm.c:590
#10 0x00000000005b482d in luaD_call (L=0x10569f0, func=0x10c1ee0,
nResults=) at ldo.c:377
#11 0x00000000005b3ab7 in luaD_rawrunprotected (L=0x10569f0,
f=0x5af680 , ud=0x7fffffffd410) at ldo.c:116
#12 0x00000000005b49c2 in luaD_pcall (L=0x10569f0, func=,
u=, old_top=64, ef=) at ldo.c:463
#13 0x00000000005b0a5f in lua_pcall (L=0x10569f0, nargs=1, nresults=0,
errfunc=) at lapi.c:821
#14 0x00000000004ac126 in pi_lua_protected_call (L=0x10569f0, nargs=1,
nresults=0) at LuaUtils.cpp:63
#15 0x00000000004a9c8e in _delete_station_ads (s=0x53ef8a0)
at LuaSpaceStation.cpp:34
#16 0x000000000051a282 in emit (impl=)
at /usr/include/sigc++-2.0/sigc++/signal.h:776
#17 emit (this=) at /usr/include/sigc++-2.0/sigc++/signal.h:2673
#18 SpaceStation::~SpaceStation (this=0x53ef8a0, __in_chrg=)
at SpaceStation.cpp:339
#19 0x000000000051a569 in SpaceStation::~SpaceStation (this=0x53ef8a0,
__in_chrg=) at SpaceStation.cpp:341
#20 0x0000000000511d6f in Space::UpdateBodies (this=0x4f6bf80) at Space.cpp:685
#21 0x0000000000511ffc in Space::~Space (this=0x4f6bf80,
__in_chrg=) at Space.cpp:92
#22 0x0000000000512199 in Space::~Space (this=0x4f6bf80,
__in_chrg=) at Space.cpp:93
#23 0x0000000000440986 in ~ScopedPtr (this=,
__in_chrg=) at SmartPtr.h:95
#24 Reset (p=0x0, this=0x4f60b90) at SmartPtr.h:22
#25 Game::~Game (this=0x4f60b90, __in_chrg=) at Game.cpp:94
#26 0x00000000004b47f8 in Pi::EndGame () at Pi.cpp:1199
#27 0x00000000004425b9 in GameMenuView::OpenLoadDialog (this=)
at GameMenuView.cpp:613
#28 0x000000000055c162 in emit (impl=)
at /usr/include/sigc++-2.0/sigc++/signal.h:776
#29 emit (this=) at /usr/include/sigc++-2.0/sigc++/signal.h:2673
#30 OnMouseUp (this=, e=) at GuiButton.cpp:37
#31 Gui::Button::OnMouseUp (this=, e=)
at GuiButton.cpp:31
#32 0x000000000055d49f in Gui::Container::HandleMouseEvent (this=0x42315f0,
e=0x7fffffffd920) at GuiContainer.cpp:93
#33 0x000000000055d49f in Gui::Container::HandleMouseEvent (this=0x4231220,
e=0x7fffffffd920) at GuiContainer.cpp:93
#34 0x000000000055d49f in Gui::Container::HandleMouseEvent (this=0x4231070,
e=0x7fffffffd920) at GuiContainer.cpp:93
#35 0x000000000055d49f in Gui::Container::HandleMouseEvent (this=0x422c110,
e=0x7fffffffd920) at GuiContainer.cpp:93
#36 0x000000000055d49f in Gui::Container::HandleMouseEvent (this=0x1056800,
e=0x7fffffffd920) at GuiContainer.cpp:93
#37 0x0000000000564889 in Gui::Screen::OnClick (e=)
at GuiScreen.cpp:198
#38 0x0000000000558f15 in Gui::HandleSDLEvent (event=0x7fffffffdb70)
at Gui.cpp:27
#39 0x00000000004b48c2 in Pi::HandleEvents () at Pi.cpp:674
#40 0x00000000004b5ef7 in Pi::MainLoop () at Pi.cpp:1275
#41 0x00000000004b774c in Pi::Start () at Pi.cpp:1180
#42 0x0000000000414a35 in main (argc=) at main.cpp:18
```

The code is quite complex, but the commit that first caused this was 40d4a28928d588fc09a652d11306fb9a66b3e500 (and the presence of `character:Save()` on the onDelete function). During play, this code performs properly, but as soon as the player quits or clicks "Load a game" the game's destructors call the onDelete function of all the adverts that exist in the system. Unfortunately, there isn't usually enough game state left at this point for reliability.