Possible bug?

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Post Reply
User avatar
loza
Kobold
Posts: 27
Joined: Tue Feb 28, 2006 11:58 am

Possible bug?

Post by loza »

I'm rather out of my depth here, but it would seem I've accidently uncovered a major bug in Ogre itself.

Please look at this thread:
(look at Clays response in particular, he's a more advanced ogre user.
on the addons forum, my name is Pikmin Doctor)
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=6466

Sorry it took me a few days to reply, I forgot to check back on the thread, but now I've reproduced the bug in C++ using some sample code from the OgreAppWizard and here it is:

Code: Select all


#include "Test.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

//running ogre first time...

#ifdef __cplusplus
	extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
		int main(int argc, char *argv[])
#endif
		{
			try
			{
				// Create application object
				TestApp app1;
				app1.go();

				//That one has run and closed now. Let's run Ogre again...
				TestApp app2;
				app2.go();
			}
			
			catch( Ogre::Exception& e ) {
			#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
							MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
			#else
							std::cerr << "An exception has occured: " <<
								e.getFullDescription().c_str() << std::endl;
			#endif
			}

			return 0;
		}

#ifdef __cplusplus
	}
#endif
Is this really a bug?
'we are the only ones who can save world!
(...of warcraft)'
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19265
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

You're creating Root twice. Don't. ;)

if you want separate scenes, just instantiate SceneManager more than once. But there can only be one Root.
User avatar
loza
Kobold
Posts: 27
Joined: Tue Feb 28, 2006 11:58 am

Post by loza »

:D ok, I'll just use multiple scenes from now on.

does this mean clay isn't right in saying this should work?

Clay:
Ogre wasn't designed with this scenario in mind, but what you are doing here should have worked. I took a look at this myself, and it looks like a bug in Ogre.
(pls check back at the link I provided to another thread at the top)
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=6466

there's a chance I might not of reproduced the problem correctly in C++

Clay
I modified an Mogre program I've been working on to do this:

Code:
static void Main()
{
RunOnce();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
RunOnce();
}


Where RunOnce is a function which looks like the Main functions in the tutorials (creates an OgreWindow, etc). The Collect/WaitForPendingFinalizers/Collect will fully cleanup the Ogre run. Then if we look at the state of the program, you can see that indeed, the ResourceGroupManager (and the _native instance it points to) are different. The AV itself takes place in Ogre itself, with CLRStack showing this:

Code:
0:000> !clrstack
OS Thread Id: 0x1744 (0)
ESP EIP
002cf170 04857e14 [NDirectMethodFrameStandalone: 002cf170] <Module>.Ogre.ResourceGroupManager.addResourceLocation(Ogre.ResourceGroupManager*, std.basic_string<char,std::char_traits<char>,std::allocator<char> >*, std.basic_string<char,std::char_traits<char>,std::allocator<char> >*, std.basic_string<char,std::char_traits<char>,std::allocator<char> >*, Boolean)
002cf18c 055512b3 Mogre.ResourceGroupManager.AddResourceLocation(System.String, System.String, System.String)
002cf21c 05550aab MogrePython.OgreWindow.InitResources()
002cf254 05550228 MogrePython.OgreWindow.InitializeOgre()
002cf280 05550153 MogrePython.OgreWindow.Go()
002cf288 006e8355 MogrePython.Program.RunOnce()
002cf2b4 006e0095 MogrePython.Program.Main()
002cf4d4 79e7c74b [GCFrame: 002cf4d4]


Looking at the native callstack we see that the AV is in Ogre itself. Note the function name is wrong, I do not have symbols loaded for release mode in Ogre:

0:000> kn3
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 002cf158 055512b3 OgreMain!Ogre::StringConverter::parseAngle+0x1ff4
01 002cf238 7b069289 0x55512b3
02 002cf2b0 79e7c74b System_Windows_Forms_ni+0x99289

What this tells us is that we are only one frame deep in OgreMain. So, this isn't likely to be an Mogre issue. I can see the problem though. It looks like Ogre!ResourceGroupManager::AddResourceLocation has called a function which returned an invalid object. AddResourceLocation then tries to dereference a field of the object and this hits an AV (remember rax is the return value in x86 calling conventions):

0:000> r
eax=baadf00d ebx=002cf1c4 ecx=00f48e5c edx=002cf18c esi=00f48e5c edi=00f48e30
eip=04857e14 esp=002cf014 ebp=002cf158 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
OgreMain!Ogre::StringConverter::parseAngle+0x1ff4:
04857e14 8b7004 mov esi,dword ptr [eax+4] ds:0023:baadf011=????????

This really does look like a bug in Ogre, but I can't find the problem here without getting the Mogre/Ogre sources and symbols for the Release version. You should do one of the following:


Repro the bug under C++ Ogre and report it to the Ogre developers.

If you have the full Visual Studio, you could use the Debug version of Mogre (I can't because I'm using C# express and don't have the Debug CRT) and find the problem using mixed-mode debugging.

You could ask the maintainer of Mogre very nicely to take a look at it, because he probably has the knowhow and setup to do this, and it's a very simple repro.
'we are the only ones who can save world!
(...of warcraft)'
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19265
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

You can destroy & recreate Root more than once, but having 2 instances of Root in a constructed state at once is invalid - that's what your code was doing. I can't tell what the example you've posted from Clay is doing, but if it's the same thing, it's not supposed to work.
User avatar
loza
Kobold
Posts: 27
Joined: Tue Feb 28, 2006 11:58 am

Post by loza »

Ok, thanks for your patiance!

ps: my repro was wrong after all. When I modified it, ogre does work no problem now. Doing exactly the same thing in the 'managed ogre (mogre) wrapper causes memory leaks you see, though I guess this is a problem for the mogre developers.

Code: Select all

#include "Test.h"

	void RunOgre()
	{
		try
		{
			// Create application object
			TestApp app1;
			app1.go();
		}
		catch( Ogre::Exception& e )
		{
			MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
		}
	}


#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

	INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
	{
		RunOgre();
		RunOgre();
		return 0;
	}
'we are the only ones who can save world!
(...of warcraft)'
Post Reply