Crash when terminating

kvchung

04-09-2010 17:09:36

Hi again,

I found someway to make my program to crash in my 2 computers

My working Environment:
Ogre 1.71
OpenAL 1.1 SDK
OgreOggSound 1.18 with thread
VC 2008
Windows 7

1. use mRoot->showConfigDialog() and press "Cancel"
here is the stack

>OgreOggSound_d.dll!OgreOggSound::LocklessQueue<OgreOggSound::SoundAction>::pop(OgreOggSound::SoundAction & obj={...}) line 96 + 0x6 bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::~OgreOggSoundManager() line 142 + 0xf bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::`scalar deleting destructor'() + 0x2b bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundPlugin::shutdown() line 65 + 0x16 bytes C++
OgreMain_d.dll!5e28df60()
OgreMain_d.dll!5e28d903()
OgreMain_d.dll!5e28a590()
Game1.exe!Ogre::Root::`scalar deleting destructor'() + 0x2e bytes C++
Game1.exe!BaseApplication::~BaseApplication() line 53 + 0x2e bytes C++
Game1.exe!Game1::~Game1() line 28 + 0x8 bytes C++
Game1.exe!WinMain(HINSTANCE__ * hInst=0x001f0000, HINSTANCE__ * __formal=0x00000000, char * strCmdLine=0x0036577f, HINSTANCE__ * __formal=0x00000000) line 159 + 0x1c bytes C++
Game1.exe!__tmainCRTStartup() line 574 + 0x35 bytes C
Game1.exe!WinMainCRTStartup() line 399 C

looks like mActionsList in OgreOggSoundManager has not been initialized but deleted.

2. Play streamed sound and exit without using "Stop"
stack:

>msvcr90d.dll!memcpy(unsigned char * dst=0x062c3a8e, unsigned char * src=0x062c04ae, unsigned long count=1) line 350 Asm
msvcr90d.dll!memcpy_s(void * dst=0x062c3a8e, unsigned int sizeInBytes=4294967295, const void * src=0x062c04ae, unsigned int count=1) line 67 + 0x11 bytes C
msvcp90d.dll!std::char_traits<char>::_Copy_s(char * _First1=0x062c3a8e, unsigned int _Size_in_bytes=4294967295, const char * _First2=0x062c04ae, unsigned int _Count=1) line 582 + 0x16 bytes C++
msvcp90d.dll!std::_Traits_helper::copy_s<std::char_traits<char> >(char * _First1=0x062c3a8e, unsigned int _Size=4294967295, const char * _First2=0x062c04ae, unsigned int _Count=1, std::_Secure_char_traits_tag __formal={...}) line 714 + 0x15 bytes C++
msvcp90d.dll!std::_Traits_helper::copy_s<std::char_traits<char> >(char * _First1=0x062c3a8e, unsigned int _Size=4294967295, const char * _First2=0x062c04ae, unsigned int _Count=1) line 706 + 0x22 bytes C++
msvcp90d.dll!std::basic_streambuf<char,std::char_traits<char> >::_Xsgetn_s(char * _Ptr=0x062c3a8e, unsigned int _Ptr_size=4294967295, int _Count=1) line 342 + 0x1a bytes C++
msvcp90d.dll!std::basic_streambuf<unsigned short,std::char_traits<unsigned short> >::_Sgetn_s(unsigned short * _Ptr=0x062c3a8e, unsigned int _Ptr_size=4294967295, int _Count=1) line 118 C++
msvcp90d.dll!std::basic_istream<char,std::char_traits<char> >::_Read_s(char * _Str=0x062c3a8e, unsigned int _Str_size=4294967295, int _Count=1) line 698 + 0x27 bytes C++
msvcp90d.dll!std::basic_istream<char,std::char_traits<char> >::read(char * _Str=0x062c3a8e, int _Count=1) line 712 C++
OgreMain_d.dll!587d37e5()
OgreOggSound_d.dll!OgreOggSound::OOSStreamRead(void * ptr=0x062c3a8e, unsigned int size=1, unsigned int nmemb=65536, void * datasource=0x06bc16b0) line 41 + 0x2b bytes C++
OgreOggSound_d.dll!_ov_open_callbacks() + 0x90a bytes
OgreOggSound_d.dll!_ov_open_callbacks() + 0x7c5 bytes
OgreOggSound_d.dll!_ov_pcm_seek() + 0xa4f bytes
OgreOggSound_d.dll!_ov_read() + 0x7b bytes
OgreOggSound_d.dll!OgreOggSound::OgreOggStreamSound::_stream(unsigned int buffer=121175880) line 333 + 0x27 bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggStreamSound::_updateAudioBuffers() line 308 + 0xc bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::_updateBuffers() line 2550 + 0x28 bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::threadUpdate() line 676 C++
OgreOggSound_d.dll!boost::detail::function::void_function_invoker0<void (__cdecl*)(void),void>::invoke(boost::detail::function::function_buffer & function_ptr={...}) line 112 + 0x5 bytes C++
OgreOggSound_d.dll!boost::function0<void>::operator()() line 1013 + 0x16 bytes C++
OgreOggSound_d.dll!boost::detail::thread_data<boost::function0<void> >::run() line 57 C++
OgreOggSound_d.dll!boost::`anonymous namespace'::thread_start_function(void * param=0x003eb360) line 168 C++
msvcr90d.dll!_callthreadstartex() line 348 + 0xf bytes C
msvcr90d.dll!_threadstartex(void * ptd=0x02440c00) line 331 C
kernel32.dll!762b1194()
ntdll.dll!77a9b495()
ntdll.dll!77a9b468()

the last log:

00:01:24: DefaultWorkQueue('Root') shutting down on thread 003468A0.
00:01:24: DefaultWorkQueue('Root')::WorkerFunc - thread 036D1B78 stopped.
00:01:24: DefaultWorkQueue('Root')::WorkerFunc - thread 036D9CB8 stopped.


3. Exit when the file is still loading

stickymango

04-09-2010 18:58:40

Hmmm, okay I'll look into those... :(

stickymango

04-09-2010 21:10:06

Had a quick check of this but was unsuccessful in getting any crashes, I'm on win 7 ultimate.. I did add some check's in the destructor of the SoundManager but I don't really see they have much influence, give it a try if you like..

If you could post some code so I can try to reproduce this that would be great, better still would be a test app if possible...

Thanks.

kvchung

05-09-2010 08:29:58

I found the solution for 1:
because I wrote "mRoot->loadPlugin("OgreOggSound")" too forward (just after "mRoot = new Ogre::Root(mPluginsCfg)")
after I move it into createScene(), it no longer crashes.
where do you recommend me to put "loadPlugin"?

and 2,3 is still happening

here is the code (but I guess it may be a general problem?)

void test1::createScene(void)
{
#ifdef _DEBUG
mRoot->loadPlugin("OgreOggSound_d");
#else
mRoot->loadPlugin("OgreOggSound");
#endif

Ogre::Entity* ogreHead = mSceneManager->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode *headNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
headNode->attachObject(ogreHead);

OgreOggSound::OgreOggSoundManager* mSoundManager = OgreOggSound::OgreOggSoundManager::getSingletonPtr();

if (mSoundManager->init())
{
if ( mSoundManager->createSound("Sound2", "music1.ogg", true, false, false) )
mSoundManager->getSound("Sound2")->play();

headNode->attachObject(mSoundManager->getListener());

OgreOggSound::OgreOggISound* newSound;
if ( newSound = mSoundManager->createSound("Sound1", "wave1.wav", false, true, false) )
{
newSound->setRolloffFactor(2.f);
newSound->setReferenceDistance(10.f);
newSound->play();
mSceneManager->getRootSceneNode()->attachObject(newSound);
}
}

// Set ambient light
mSceneManager->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

// Create a light
Ogre::Light* l = mSceneManager->createLight("MainLight");
l->setPosition(20,80,50);
}

Notice that my testing computer is very slow (EeePC 1000H)
and the music "music1.ogg" is about 5mb

reproduce it by interrupt the loading and playing of the sounds

stickymango

05-09-2010 15:59:35

1) do you not add the OgreOggSound plugin to the plugins.cfg file? If so you don't need to explicitly load it aswell...
2/3) I think there may be a caveat when loading and closing at the same time, I'll try and see if I can trace it and think of a solution, but the main problem is intercepting destruction outside of the sound manager which is what happens when you delete Root... I think 2 suffers from this too.

kvchung

19-09-2010 16:53:06

the problem 2 still happened (crash when terminating) randomly
does anyone have the same problem or just me?

stickymango

19-09-2010 22:56:38

Are you using the latest SVN code?

how do you shutdown OgreOggSound?

Could you supply a demo application?

kvchung

20-09-2010 19:08:32

I've updated to r350 and observing

I didn't do anything to shutdown OgreOggSound
once I use OgreOggSound::OgreOggSoundManager::getSingletonPtr()->destroyAllSounds();
it will crash

stickymango

21-09-2010 12:50:41

I've identified a bug with destroyAllSounds(), leave it with me :oops:

stickymango

21-09-2010 21:37:07

Hi kvchung,

Please try a fresh checkout from SVN, hopefully shutdown issues should now be fixed, reworked destruction of sounds to hopefully fixed any thread safety issues.

kvchung

03-10-2010 06:01:05

(sorry for disappearing for a long time)

After I upgrade OgreOgreSound from r350 to the latest
1. OgreOggSound::OgreOggSoundManager::getSingleton().destroyAllSounds() does not crash anymore
2. OgreOggSound::OgreOggSoundManager::getSingleton().destroySound() does not work anymore
3. OgreOggSound::OgreOggSoundManager::getSingleton().destroyAllSounds() only stops the sounds without attached to a node
(only the background music has been stopped)

stickymango

03-10-2010 20:37:39

Hi kvchung,

At what point do you call these functions? destroySound() now requires update() to be called to actually destroy the sounds.

I can't understand why attached sounds would be omitted, I'll try to test that.

kvchung

04-10-2010 10:09:44

Hi,
I use these between game states (like this http://www.ogre3d.org/tikiwiki/tiki-ind ... %20Manager).

destroySound() is working after I added update() to the global frame listener :D
destroyAllSounds() also works this time (but I didn't do any changes)

And I think destroyAllSounds() is a little unstable with streamed sounds in thread mode.
in threadUpdate(), OgreOggSoundManager::_updateBuffers() will be called

// Loop all active sounds
ActiveList::const_iterator i = mActiveSounds.begin();
while( i != mActiveSounds.end())
{
// update pos/fade
(*i)->update(fTime);

// Update buffers
---------->(*i)->_updateAudioBuffers();

// Update recorder
if ( mRecorder ) mRecorder->_updateRecording();

// Next..
++i;
}

Sometimes, it run into the loop but "*i" had been destroyed in main thread.
and OgreOggStreamSound::_stream(), which will be called later will crash

stickymango

04-10-2010 10:17:07

Sounds like progress :D

The only cuplrit for that crash is the ActiveSounds list, which should get updated after every sound is deleted, there's a mutex lock used now so that the app doesn't dop into threadUpdate() until the lists and destruction has been completed, I'll have a scan through that to check...

kvchung

04-10-2010 11:03:12

In this situation, mActiveSounds had been truely updated.
But it run into the while loop first, and than mActiveSounds updates.
The sequence is like
1. ActiveList::const_iterator i = mActiveSounds.begin();
while( i != mActiveSounds.end())
...
2. the lists and destruction has been completed
3. (*i)->_updateAudioBuffers();

stickymango

04-10-2010 11:13:48

Hmmm,

That shouldn't be possible because of the mutex lock.

OgreOggSoundManager::update() should hang until threadUpdate() reliquishes control, which would be at the end of its scope, then the destruction happens, lists updated etc.. then update() exits and threadUpdate() is free to start again..

I had a similar experience when I was debugging the lib which was caused by invalid #defines for BOOST_THREAD, should be fixed, and also a slightly different version of OGRE dll's, perhaps you can double check they are all matching?

Otherwise the locking should prevent what your experiencing.

kvchung

04-10-2010 12:02:52

I'm sure my Ogre dlls are 1.7.1 because this is my first time using Ogre.
And I did not really understand what you were saying due to the language gap or my technique problem(I have no experience dealing with thread problems)

btw I'm using destroyAllSounds(), so OgreOggSoundManager::update() does not have to be called, right?

stickymango

04-10-2010 12:08:54

Yeah, you shouldn't have to call update if using destroyAllSounds().

[edit] Further to this, I've now removed the need to call update to destroy sounds, destroySound() now acts immediately, at present temporary sounds stil require update() to be called so they can be cleaned up in the background, however I plan to change this too. [/edit]