Game Development Community

Sigsegv On Quit()

by Jeremy Slade · in Torque Game Engine · 01/04/2006 (7:42 am) · 5 replies

I'm trying to add a -fast command-line option to bypass menus and such and go straight into my mission, for testing purposes. The problem is when I want to quit -- I added the following in default.bind.cs

function escapeFromGame()
{
  if ( $Startup::fast ) {
    disconnect();
    quit();
    return;
  }

 ...
}

When I hit escape, the engine crashes with a SIGSEGV, and from gdb I get:

Program received signal SIGSEGV, Segmentation fault.
0xcececece in ?? ()
(gdb) bt
#0  0xcececece in ?? ()
#1  0x0042fc43 in Con::_printf (level=Warning, type=General, 
    fmt=0x7c50d0 "Error, a %s (%x) isn't properly out of the bins!", 
    argptr=0x23fee8 "G]z") at console/console.cc:494
#2  0x0042fdfd in Con::warnf (
    fmt=0x7c50d0 "Error, a %s (%x) isn't properly out of the bins!")
    at console/console.cc:559
#3  0x006219cb in Container::~Container (this=0x88ed10)
    at sim/sceneObject.cc:825
#4  0x0062678a in __static_initialization_and_destruction_0 (
    __initialize_p=0, __priority=65535) at sim/sceneObject.cc:774
#5  0x0062683b in global destructors keyed to _ZNK11SceneObject11getClassRepEv
    () at sim/sceneObject.cc:2205
#6  0x00714bc2 in __do_global_dtors () at ./platform/event.h:155
#7  0x77c39e24 in msvcrt!_initterm () from /c/WINDOWS/system32/msvcrt.dll
#8  0x00000000 in ?? () from

The address 0xcececece sure looks suspicious -- is it a special marker value?


As a workaround, I added a shutdown gui the displays the GG for .5 sec then exits (modeled on the StartupGui)... if that is in there, it shuts down cleanly. Why would that be necessary? Is there some other cleanup step that I'm missing?

About the author

Recent Threads

  • Forums RSS feed

  • #1
    01/04/2006 (10:47 pm)
    So I was wrong before about the Shutdown gui allowing this to work - it is a GuiFadinBitmalCtrl, copied directly from the Startup.gui, and all it does is call quit() after the fadein process is done. But even with this code in there, it still gets the SIGSEGV:

    function escapeFromGame()
    {
      if ( $Startup::fast ) {
        disconnect();
        loadShutdown();
        return;
      }
      ...
    }
    
    function loadShutdown()
    {
      StartupGui.done = false;
      Canvas.setContent( ShutdownGui );
      schedule(100, 0, checkShutdownDone );
    }
       
    function checkShutdownDone()
    {
       if (ShutdownGui.done)
         quit();
       else
          schedule(100, 0, checkShutdownDone );
    }

    But this is what's strange to me: If I just use schedule() to call quit() like this, it works fine, shuts down with no errors:

    function escapeFromGame()
    {
      if ( $Startup::fast ) {
        disconnect();
        schedule(1000, 0, quit );
        return;
      }
      ...
    }

    That is, this method works as long as the delay is long enough. If it is shorter, say 100 instead of 1000, then it still dies with a SIGSEGV.

    I think that the only reason this isn't seen in normal use of TGE is because the default implementation of escapeFromGame() sends the user back to the MainMenu (in disconnect()), and then the user has to click on a button to quit -- which has some inherent delay, meaning that the even loop runs a few iterations, allowing the cleanup handlers to execute. But when I call quit() directly, that doesn't happen.

    Can anyone explain this? Is there something else I can call directly to get the cleanup to happen correctly?
    #2
    01/05/2006 (12:38 am)
    You are just running into the need to give all of the destructors time to get called and have the object get cleaned up. It's not obvious from your stack trace, but you are most probably running into an Assert that is keeping track of the state of the bins, and complaining that cleanup wasn't complete.
    #3
    01/08/2006 (2:12 am)
    Basically, some particle emitters like to hang about until all their particles die. Which means they're in the scenegraph when it gets shut down. You can safely comment out the Assert, though it's useful for catching naught things like objects that don't remove themselves and just build up in the scenegraph, slowing things down and wasting resources.
    #4
    02/28/2006 (4:25 pm)
    @Stephen
    and
    @Ben

    Actually in our game we have noticed a problem with the actual memory value 0xCECECECE. The problem appears in simbase.cc in the following function (with the included but ugly hack).


    SimObject::Notify* SimObject::removeNotify(void *ptr, SimObject::Notify::Type type)
    {
    
       Notify **list = &mNotifyList;
       [b]if ((int)*list == (int)0xCECECECE) return NULL;  //Ugliness [/b]
       while(*list)
       {
          if((*list)->ptr == ptr && (*list)->type == type)
          {
             SimObject::Notify *ret = *list;
             *list = ret->next;
             return ret;
          }
          list = &((*list)->next);
       }
       return NULL;
    }

    If we don't put that line in, the program will crash. Of Note: We are running in Windows and at the moment I don't remember specifically when the crash happens or under what circumstances. I thought it was at some very random times. This bug is in 1.3 and 1.4.
    -Joe
    #5
    03/06/2006 (10:33 am)
    Hmm, one thing I have noticed with shutting down is that the engine crashes if any sounds are left playing.