Page 1 of 1

Exception when destroying windows in 0.5.0

Posted: Tue Feb 06, 2007 10:33
by mba
Hi all

I'm in the process of upgrading to 0.5.0, but I'm experiencing some troubles when I exit my application. During the shutdown all windows are destroyed with

Code: Select all

WindowManager::getSingleton().destroyWindow(my_window);

but this causes an exception.

the callstack is
#0 __cxa_pure_virtual()
#1 WindowRendererManager::destroyWindowRenderer()
#2 Window::destroy()
#3 WindowManager::destroyWindow()
#4 WindowManager::destroyWindow()
#5 Window::cleanupChildren()
#6 Window::destroy
#7 WindowManager::destroyWindow()

this looks a bit funny, can anybody explain why this exception happens?

Kind regards
Martin

Posted: Tue Feb 06, 2007 12:00
by scriptkid
Are you using C++ or a binding? In case of C++: do you call 'destroyWindow'? CEGUI does a cleanup by itself, so you don't have to call it when your application quits.

I remember a 'pure virtual' crash when using a python binding when a reference was (tried to get) deleted twice. Maybe that can be a hint...

Posted: Tue Feb 06, 2007 15:02
by mba
Thanks for replying scriptkid (seems like you always are around to answer my questions :-))

Im using pure C++, no bindings.
Yes I'm calling destroyWindow, but the crash occurs before the destructor where I do the deletion of the gui renderer and the gui system.
It shouldn't cause an exception trying to manually clean up some resources, even though cegui cleans up during shutdown, should it? It didn't do that before with 0.4.1

Kind regards
Martin

Posted: Tue Feb 06, 2007 21:59
by spannerman
Can you check the error log, we might see which window in particular is causing this. I think there may still be a problem with destroying scrollable panes, are you using any in your app?

Posted: Wed Feb 07, 2007 08:33
by mba
Hi spannerman

yeah I read the posts about exceptions when destroying the scrollable pane before I posted my issue, they seem identical, but if they are many more should see this behavior when destroying windows.

just for the record, I'm using CEGUI 0.5.0b (had some issues, but now its running)

The layout contains a standard window with a standard framewindow and some standard buttons, nothing fancy like scrollable panes :-).

I load my layouts through loadWindowLayout, use them for a while, and when I exit I call destroyWindow on them for cleaning up. Even though the system cleans up resources automatically during shutdown, I like to manually keep track of what I allocate and deallocate.

regards
Martin

Posted: Wed Feb 07, 2007 18:06
by spannerman
Hmm ok, its a strange one. So is your error log completely unhelpful - can you post it here?
Also, what happens if you dont call destroywindow yourself? Does it exit fine with no errors?

Posted: Thu Feb 08, 2007 15:42
by mba
Hi spannerman, thanks for helping me out on this thing...

The CEGUI error log only contains information about succesful operations, where the last entry is:
succesfully completed loading GUI layout from...

and the console output only shows one error which is:
pure virtual method called

I have debugged the application with gdb, and I'm sure that its the destroyWindowRenderer that causes the exception.

I know this isn't much to go on, especially when I'm the only one that has this particular problem. Therefore I compiled and installed both Ogre and CEGUI in debug mode (I think :roll: ). But I can't set a breakpoint in the destructor where my window is destroyed because of a problem with gdb/gcc, so I can't trace it further. But I have made some printf :oops: debugging in the destroyWindowRenderer method where the problem arises:

Code: Select all

void WindowRendererManager::destroyWindowRenderer(WindowRenderer* wr)
{
    printf("Window Renderer Manager: destroyWindowRenderer\n");
    printf("Window Renderer Manager: destroyWindowRenderer: %s\n", wr->getName().c_str());   
    WindowRendererFactory* factory = getFactory(wr->getName());
    if(!factory) printf("getfactory returned crap\n");
    factory->destroy(wr);
    printf("Window Renderer Manager: destroyWindowRenderer: finished\n");   
}


and the output is
Window Renderer Manager: destroyWindowRenderer
Window Renderer Manager: destroyWindowRenderer: Falagard/FrameWindow
pure virtual method called


so I guess its something in the factory->destroy() call, but this is as far as I got because I can't seem to find any WindowRendererFactor class.

Kind regards
Martin Bang Andersen

Posted: Thu Feb 08, 2007 16:07
by mba
oh just found the implementation (I guess)

Code: Select all

// define factory
#define CEGUI_DEFINE_WR_FACTORY( className )\
namespace CEGUI {\
class className ## WRFactory : public WindowRendererFactory\
{\
public:\
    className ## WRFactory(void) : WindowRendererFactory(className::TypeName) { }\
    WindowRenderer* create(void)\
    { return new className(className::TypeName); }\
    void destroy(WindowRenderer* wr)\
    { delete wr; }\
};\
}\


but I need a little help deciphering it... I am completely unable to read macro-code like above ;-).
I guess that the factory hasn't been declared for some reason in the above macro, and thats why I get a pure virtual exception, because the destroy method is declared as pure virtual in the Factory class definition.

edit:
I have a log entry where renderer factory is added:
WindowRendererFactory 'Falagard/FrameWindow' added.

And another thought, why would the RendererFactory be destroyed when you destroy a window, this seems odd to me, but maybe I just doesn't understand the internal architecture well enough.

Posted: Wed Feb 14, 2007 10:09
by spannerman
Hi mba, did you manage to solve this problem? If you havent yet, I strongly suggest building in full debug mode and stepping through.