Exceptional madness
Posted: Sat Mar 14, 2009 15:08
I seem to have found a rather obscure issue with the expat parser module - getting a segfault when an exception thrown from that module is destructed.
Main function
The segfault occurs as soon control leaves the CEGUI::Exception catch block.
Here's the catch. The segfault only happens with an exception thrown when the expat parser throws for a malformed xml file. No problem with any other CEGUI exceptions that I've encountered so far. And, it only happens if the exception propogates back to the main function. Catch it as soon as it's thrown - no problem.
So then, the GameStateManager ctor
And GameStateManager::StartCEGUI, where the exception is thrown (loading the scheme).
So to review:
Only exceptions from the expat parser. Only if they propogate back to main.
Just in case there was a problem with the 0.6.2 SDK I built 0.6.2 from source, still get the segfault. Here's a disassembly and call stack after the segfault: http://uberspeedo.googlepages.com/exception.jpg
I have no idea what the problem might be, but there you have it.
Main function
Code: Select all
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
void ReportException(const char* const msg)
{
MessageBox(0, msg, "An exception occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
#else
void ReportException(const char* const msg)
{
std::cerr << msg << std::endl;
}
int main(int argc, char** argv)
#endif
{
// setup logs
Ogre::LogManager logMgr;
logMgr.createLog("Ogre.log", true, false);
logMgr.createLog("MekWars.log", false, false);
logMgr.createLog("Console", false, false, true);
logMgr.setLogDetail(Ogre::LL_BOREME);
logMgr.getLog("MekWars.log")->setLogDetail(Ogre::LL_BOREME);
logMgr.getLog("Console")->setLogDetail(Ogre::LL_BOREME);
logMgr.getLog("MekWars.log")->logMessage("MechWars Version " + VersionString( ));
try
{
// start and run the game
GameStateManager game;
GameStateManager::GameStatePtr menu(new MainMenuState);
game.QueueStateChange(GameStateManager::Action_Push, menu);
game.Run( );
}
catch (const CEGUI::Exception& e)
{
std::string msg = "Exception \"" + std::string(e.getMessage( ).c_str( )) + "\", file: " +
std::string(e.getFileName( ).c_str( )) + " line: " +
boost::lexical_cast<std::string>(e.getLine( ));
logMgr.getLog("MekWars.log")->logMessage(msg, Ogre::LML_CRITICAL);
ReportException(msg.c_str( ));
}
catch (const std::exception& e)
{
logMgr.getLog("MekWars.log")->logMessage(e.what( ), Ogre::LML_CRITICAL);
ReportException(e.what( ));
}
return 0;
}
The segfault occurs as soon control leaves the CEGUI::Exception catch block.
Here's the catch. The segfault only happens with an exception thrown when the expat parser throws for a malformed xml file. No problem with any other CEGUI exceptions that I've encountered so far. And, it only happens if the exception propogates back to the main function. Catch it as soon as it's thrown - no problem.
So then, the GameStateManager ctor
Code: Select all
GameStateManager::GameStateManager( )
: m_configMgr(new ConfigManager),
m_root(new Ogre::Root("", "", "")),
m_window(nullptr),
m_guiRenderer( ),
m_guiSystem( ),
m_inputMgr( ),
m_soundMgr( ),
m_gameTime( ),
m_lastTime(0)
{
LoadPlugins( );
AddResourceLocations( );
CreateRenderSystem( );
CreateRenderWindow( );
CreateScene( );
InitializeResources( );
StartOIS( );
StartCEGUI( );
}
And GameStateManager::StartCEGUI, where the exception is thrown (loading the scheme).
Code: Select all
void GameStateManager::StartCEGUI( )
{
// create CEGUI components
m_guiRenderer.reset(new CEGUI::OgreCEGUIRenderer(m_window,
Ogre::RENDER_QUEUE_OVERLAY, false, 0, m_root->getSceneManager("default")));
m_guiSystem.reset(new CEGUI::System(m_guiRenderer.get( )));
CEGUI::Logger::getSingleton( ).setLoggingLevel(CEGUI::Informative);
m_guiSystem->getResourceProvider( )->setDefaultResourceGroup("gui");
CEGUI::SchemeManager::getSingleton( ).loadScheme("TaharezLook.scheme");
m_guiSystem->setDefaultTooltip("TaharezLook/Tooltip");
m_guiSystem->setDefaultMouseCursor("TaharezLook", "MouseArrow");
}
So to review:
Only exceptions from the expat parser. Only if they propogate back to main.
Just in case there was a problem with the 0.6.2 SDK I built 0.6.2 from source, still get the segfault. Here's a disassembly and call stack after the segfault: http://uberspeedo.googlepages.com/exception.jpg
I have no idea what the problem might be, but there you have it.