[SOLVED!!] Access Violation while Subscribing to an Event

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Thu Feb 07, 2008 09:46

Some more questions - and your need to get down and dirty with the debugger...

I know it works when you remove the event subscription, but does it die on the actual subscribe line? Or perhaps some time afterwards? Can you single step through your code, what happens when you try to step over that line?

If it does fail on the subscribe line, can you step into that code - does it die on the subscription call itself, or maybe prior to that when creating the Event::Subscriber object? Since you're an SDK guy, some of this means stepping through the disassembly, but it should still be possible to work out what's going on.

I get the feeling that the eventual solution to this is going to be so very simple. :lol:

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Thu Feb 07, 2008 10:56

The application crashes within InitWidgets(). Please post that code. The application does not seem to go beyond that function. You should place a breakpoint on every instruction within InitWidgets() and pinpoint which one generates the problem.

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Thu Feb 07, 2008 17:20

Yeah, the event subscriber line is the specific line it crashes on. I tried Step Over once I got to it, but it crashed when I did so.

I'll do my best to accurately describe what happens when I 'Step Into' starting with the breakpoint at the event subscriber line.

1. Breakpoint

Code: Select all

FileNew->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&Interface::TestFunction, this));

2. Step Into (to templatised subscriberslot constructor)

Code: Select all

    template<typename T>
    SubscriberSlot(bool (T::*function)(const EventArgs&), T* obj) :
        d_functor_impl(new MemberFunctionSlot<T>(function, obj))
    {}

3. Step Into (to MemberFunctionSlot constructor)

Code: Select all

    MemberFunctionSlot(MemberFunctionType func, T* obj) :
        d_function(func),
        d_object(obj)
    {}

4. Step Into (back to templatised subscriberslot constructor)

Code: Select all

    template<typename T>
    SubscriberSlot(bool (T::*function)(const EventArgs&), T* obj) :
        d_functor_impl(new MemberFunctionSlot<T>(function, obj))
    {}

5. Step Into (back to event subscription)

Code: Select all

FileNew->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&Interface::TestFunction, this));


Now when I 'Step Into' once more (starting back on the event subscription line) it crashes with the Access Violation. I cannot Step Over here, either.

So I think that means that my Event::Subscriber() goes fine, but calling the subscribeEvent with those arguments crashes?
Here is what happens if I view the Disassembly starting after the 5th Step Into (when the next Step Into would crash):

Code: Select all

00420D7D  mov         dword ptr [ebp-2740h],eax
00420D83  mov         eax,dword ptr [ebp-2740h]
00420D89  mov         dword ptr [ebp-2744h],eax
00420D8F  mov         dword ptr [ebp-4],0Fh
00420D96  mov         esi,esp
00420D98  mov         ecx,dword ptr [ebp-2744h]
00420D9E  mov         edx,dword ptr [ecx]
00420DA0  push        edx 
00420DA1  mov         eax,dword ptr [__imp_CEGUI::MenuItem::EventClicked (440570h)]
00420DA6  push        eax 
00420DA7  lea         ecx,[ebp-1F64h]
00420DAD  push        ecx 
00420DAE  mov         ecx,dword ptr [ebp-5Ch]
00420DB1  add         ecx,20h
00420DB4  mov         edx,dword ptr [ebp-5Ch]
00420DB7  mov         eax,dword ptr [edx+20h]
00420DBA  mov         edx,dword ptr [eax+8]

It starts at the first line and crashes on the last.
I'll do my best to look at this myself, but my knowledge of assembly is mostly limited to changing JNZ's and JMP's in programs for nefarious purposes :roll:

Rackle: As you requested, here is the entirety of the InitWidgets() function, if you still want to see it. I left in all code for completeness' sake. Also included is the referenced member function.

Code: Select all

void Interface::InitWidgets()
{
   WindowManager& wmgr = WindowManager::getSingleton(); // Init pointer to Window Manager
   Window* Root = wmgr.createWindow("DefaultWindow", "root"); // Create root window
   System::getSingleton().setGUISheet(Root); // Set root window

   Window* Menubar = wmgr.createWindow("WindowsLook/Menubar", "root/menubar");
   Menubar->setSize(UVector2(cegui_reldim(1.0f), cegui_reldim(0.06f)));
    Menubar->setAlwaysOnTop(true);
   Root->addChildWindow(Menubar);
   
      MenuItem* File = static_cast<MenuItem*>(wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/file"));
      File->setText("File");
      Menubar->addChildWindow(File);
      
         PopupMenu* FilePopup = static_cast<PopupMenu*>(wmgr.createWindow("WindowsLook/PopupMenu", "root/menubar/file/popup"));
         File->addChildWindow(FilePopup);
   
            MenuItem* FileNew = static_cast<MenuItem*>(wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/file/popup/new"));
            FileNew->setText("New");
            FilePopup->addChildWindow(FileNew);
            FileNew->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&Interface::TestFunction, this));
   
            MenuItem* FileOpen = static_cast<MenuItem*>(wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/file/popup/open"));
            FileOpen->setText("Open");
            FilePopup->addChildWindow(FileOpen);
   
            MenuItem* FileSave = static_cast<MenuItem*>(wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/file/popup/save"));
            FilePopup->addChildWindow(FileSave);
            FileSave->setSize(UVector2(cegui_reldim(0.2f), cegui_reldim(0.05f)));
            FileSave->setText("Save");

            MenuItem* FileExit = static_cast<MenuItem*>(wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/file/popup/exit"));
            FilePopup->addChildWindow(FileExit);
            FileExit->setSize(UVector2(cegui_reldim(0.2f), cegui_reldim(0.05f)));
            FileExit->setText("Exit");

      Window* View = wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/view");
      Menubar->addChildWindow(View);
      View->setText("View");

         PopupMenu* ViewPopup = static_cast<PopupMenu*>(wmgr.createWindow("WindowsLook/PopupMenu", "root/menubar/view/popup"));
         View->addChildWindow(ViewPopup);
         ViewPopup->setSize(UVector2(cegui_reldim(2.5f), cegui_reldim(5.5f)));

            MenuItem* ViewFullscreen = static_cast<MenuItem*>(wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/view/popup/fullscreen"));
            ViewPopup->addChildWindow(ViewFullscreen);
            ViewFullscreen->setText("Toggle Fullscreen");


   TabControl* Tabs = static_cast<TabControl*>(wmgr.createWindow("WindowsLook/TabControl", "root/tabs"));
   Root->addChildWindow(Tabs);
   Tabs->setSize(UVector2(cegui_reldim(0.2f), cegui_reldim(0.94f)));
   Tabs->setPosition(UVector2(cegui_reldim(0.8f),cegui_reldim(0.06f)));

      Window* TabTiles = wmgr.createWindow("DefaultWindow", "root/tabs/tiles");
      TabTiles->setText("Tiles");
      Tabs->addChildWindow(TabTiles);

      Window* TabObjects = wmgr.createWindow("DefaultWindow", "root/tabs/objects");
      TabObjects->setText("Objects");
         TabControl* ObjectsTabs = static_cast<TabControl*>(wmgr.createWindow("WindowsLook/TabControl","root/tabs/objectstabs"));
         TabObjects->addChildWindow(ObjectsTabs);
         ObjectsTabs->setSize(UVector2(cegui_reldim(1.0f), cegui_reldim(1.0f)));
         ObjectsTabs->setPosition(UVector2(cegui_reldim(0.0f),cegui_reldim(0.0f)));
            
            Window* ObjectsTabStatics = wmgr.createWindow("DefaultWindow", "root/tabs/objects/statics");
            ObjectsTabStatics->setText("Statics");
            ObjectsTabs->addChildWindow(ObjectsTabStatics);

            Window* ObjectsTabDynamics = wmgr.createWindow("DefaultWindow", "root/tabs/objects/dynamics");
            ObjectsTabDynamics->setText("Dynamics");
            ObjectsTabs->addChildWindow(ObjectsTabDynamics);
      Tabs->addChildWindow(TabObjects);

      Window* TabBeings = wmgr.createWindow("DefaultWindow", "root/tabs/beings");
      TabBeings->setText("Beings");
         TabControl* BeingsTabs = static_cast<TabControl*>(wmgr.createWindow("WindowsLook/TabControl","root/tabs/beingstabs"));
         TabBeings->addChildWindow(BeingsTabs);
         BeingsTabs->setSize(UVector2(cegui_reldim(1.0f),cegui_reldim(1.0f)));
         BeingsTabs->setPosition(UVector2(cegui_reldim(0.0f),cegui_reldim(0.0f)));
            
            Window* BeingsTabEnemies = wmgr.createWindow("DefaultWindow", "root/tabs/beings/enemies");
            BeingsTabEnemies->setText("Enemies");
            BeingsTabs->addChildWindow(BeingsTabEnemies);
            
            Window* BeingsTabNPCs = wmgr.createWindow("DefaultWindow", "root/tabs/beings/npcs");
            BeingsTabNPCs->setText("NPCs");
            BeingsTabs->addChildWindow(BeingsTabNPCs);
      Tabs->addChildWindow(TabBeings);
}

bool Interface::TestFunction(const CEGUI::EventArgs &args)
{
   return true;
}


I haven't checked if the TabControl part is still working since I started using the new CEGUI version, but it doesn't get their regardless.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Fri Feb 08, 2008 09:22

It's getting hard to fathom what this could be - since the samples built and run, it must be something external.

Are the config settings for the runtime (still) correct - Multithreaded DLL (and debug version for debug build)?
Are you remembering to link to the _d version of the libs (like CEGUIBase_d.lib) for the debug config and the ones without the suffix for release?
You wouldn't be using some kind of memory manager or something?
Are you using any other libs at all?

There's got to be something that's causing it!

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Sun Feb 10, 2008 19:26

I'm just using OpenGL, SDL, and this.
I've made sure the runtime is set to multithreaded DLL debug for debug etc.
I'm really not using anything weird :[
Idk. I think I'm going to set this on the shelf for now.. @_@

Thanks for all your help, though. I appreciate it a lot :]
If I manage to fix it, I'll post here so you guys know how it worked out.

[EDIT]: I was re-reading your post. I didn't realize that .lib's I Linked to were specific to a configuration. Like, I thought that those were linked in debug and runtime, so I had both .lib's and _d.lib's listed.
Fixing that solved the problem!

I can't thank you guys enough for all your help. All the time you put into my problem is absolutely insane; you really saved my program :]


Return to “Help”

Who is online

Users browsing this forum: No registered users and 20 guests