Help debugging failed assert( msSingleton );

Get answers to all your basic programming questions. No Ogre questions, please!
chilly willy
Halfling
Posts: 65
Joined: Tue Jun 02, 2020 4:11 am
x 19

Help debugging failed assert( msSingleton );

Post by chilly willy »

Ogre Version: 14.1
Operating System: macOS Catalina 10.15.5

I rebuilt OGRE from the latest repo and now when my projects go to load OGRE plugins it crashes. I tried the Sample Browser and it does the same thing. It is failing assert( msSingleton ) inside Root::getSingleton();

I stepped through the code and I see the Root getting created and msSingleton is assigned the pointer. Inside Root::loadPlugins() the watch window shows msSingleton having the correct value but when it calls Root::loadPlugin() the watch window shows msSingleton being NULL. Then Root::loadPlugin() calls dllStartPlugin() (through pFunc) and in dllStartPlugin() a watch on Ogre::Root::msSingleton shows the correct value again. Then dllStartPlugin() calls Root::getSingleton() and inside that function a watch on msSingleton shows NULL and it fails the assert.

Anybody have any idea what is going on? I will delete everything and try a clean build but I'd still like to understand how this happened.

paroj
OGRE Team Member
OGRE Team Member
Posts: 2108
Joined: Sun Mar 30, 2014 2:51 pm
x 1134

Re: Help debugging failed assert( msSingleton );

Post by paroj »

ABI changes most likely. Did you rebuild the plugins also? The issue would be that the plugins use an old header compared to master and look-up class members at the wrong offset.

chilly willy
Halfling
Posts: 65
Joined: Tue Jun 02, 2020 4:11 am
x 19

Re: Help debugging failed assert( msSingleton );

Post by chilly willy »

paroj wrote: Fri Sep 15, 2023 10:59 am

Did you rebuild the plugins also?

Yes, I had deleted the entire previous build.

I did another clean build and it works now. I think the difference may have been whether I set OGRE_BUILD_LIBS_AS_FRAMEWORKS or not. I will mess with it some more tonight/this weekend and see if I can recreate the problem.

But I have a new problem/question. When I used to build OGRE it would spit out all of the plugins (or maybe they were symlinks) in a single folder (sdk/lib/OGRE) so I was using that as my "PluginFolder" in plugins.cfg (using OgreBites). Now it does not create a single folder with all the plugins (or symlinks) so I'm not sure how to use the plugins.cfg file to load multiple plugins from different subfolders. Was this intentional? Did I build it wrong?

rpgplayerrobin
Gnoll
Posts: 686
Joined: Wed Mar 18, 2009 3:03 am
x 379

Re: Help debugging failed assert( msSingleton );

Post by rpgplayerrobin »

Aren't those directories created when you compile the INSTALL project or something?

chilly willy
Halfling
Posts: 65
Joined: Tue Jun 02, 2020 4:11 am
x 19

Re: Help debugging failed assert( msSingleton );

Post by chilly willy »

rpgplayerrobin, yes, the sdk/lib/OGRE directory is created when I compile the INSTALL project, but the plugins are not copied to it (nor are symlinks created in it). At least that's what happened last night. I will try again tonight.

BTW so far I've just been learning and developing and never released anything so it's kinda messy while I'm still learning. But how do you handle this kind of stuff when you publish your game? How do you decide between static and dynamic linking? Do you use OGRE's plugins.cfg file? Do you use OGRE's getConfigFilePath() or getWritablePath() to store settings? Do you use an installer?

paroj
OGRE Team Member
OGRE Team Member
Posts: 2108
Joined: Sun Mar 30, 2014 2:51 pm
x 1134

Re: Help debugging failed assert( msSingleton );

Post by paroj »

to be honest, I never got to look into the the framework stuff on OSX or why somebody should use them. I just know that the sample browser only runs with frameworks as of now.

When shipping ogre via tha PIP package on OSX, frameworks are disabled.

However, there was an issue reported for frameworks recently, so you might chime in the discussion there:
https://github.com/OGRECave/ogre/issues/2926

rpgplayerrobin
Gnoll
Posts: 686
Joined: Wed Mar 18, 2009 3:03 am
x 379

Re: Help debugging failed assert( msSingleton );

Post by rpgplayerrobin »

rpgplayerrobin, yes, the sdk/lib/OGRE directory is created when I compile the INSTALL project, but the plugins are not copied to it (nor are symlinks created in it). At least that's what happened last night. I will try again tonight.

It seems I forgot how I handled this, because I rarely compile the engine.
I use a .bat file that I place in C:\OgreSDK that gathers all files that I want.
Here is the code for it, but you might need to alter it a bit for your needs:

Filename: GatherFiles.bat

Code: Select all

xcopy /s /v /y "C:\OgreSDK\ogre\build\bin\debug\*.dll" "C:\OgreSDK\bin"
xcopy /s /v /y "C:\OgreSDK\ogre\build\bin\debug\*.exe" "C:\OgreSDK\bin"

xcopy /s /v /y "C:\OgreSDK\ogre\build\bin\release\*.dll" "C:\OgreSDK\bin"
xcopy /s /v /y "C:\OgreSDK\ogre\build\bin\release\*.exe" "C:\OgreSDK\bin"

xcopy /s /v /y "C:\OgreSDK\ogre\build\lib\Debug\*.lib" "C:\OgreSDK\lib\Debug"
xcopy /s /v /y "C:\OgreSDK\ogre\build\lib\Release\*.lib" "C:\OgreSDK\lib\Release"

xcopy /s /v /y "C:\OgreSDK\ogre\build\Dependencies\lib\zlib.lib" "C:\OgreSDK\lib\Release"
xcopy /s /v /y "C:\OgreSDK\ogre\build\Dependencies\lib\zlib.lib" "C:\OgreSDK\lib\Debug"

xcopy /s /v /y "C:\OgreSDK\SDL2Specific\lib\SDL2.lib" "C:\OgreSDK\lib\Release"
xcopy /s /v /y "C:\OgreSDK\SDL2Specific\lib\SDL2.lib" "C:\OgreSDK\lib\Debug"
xcopy /s /v /y "C:\OgreSDK\SDL2Specific\lib\SDL2main.lib" "C:\OgreSDK\lib\Release"
xcopy /s /v /y "C:\OgreSDK\SDL2Specific\lib\SDL2main.lib" "C:\OgreSDK\lib\Debug"



xcopy /s /v /y "C:\OgreSDK\ogre\OgreMain\include" "C:\OgreSDK\include\OGRE"
xcopy /s /v /y "C:\OgreSDK\ogre\build\include" "C:\OgreSDK\include\OGRE"
xcopy /s /v /y "C:\OgreSDK\ogre\Samples\Common\include\ListenerFactoryLogic.h" "C:\OgreSDK\include\OGRE"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\Bites\include" "C:\OgreSDK\include\OGRE\Bites"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\HLMS\include" "C:\OgreSDK\include\OGRE\HLMS"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\MeshLodGenerator\include" "C:\OgreSDK\include\OGRE\MeshLodGenerator"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\Overlay\include" "C:\OgreSDK\include\OGRE\Overlay"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\Paging\include" "C:\OgreSDK\include\OGRE\Paging"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\Property\include" "C:\OgreSDK\include\OGRE\Property"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\RTShaderSystem\include" "C:\OgreSDK\include\OGRE\RTShaderSystem"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\Terrain\include" "C:\OgreSDK\include\OGRE\Terrain"
xcopy /s /v /y "C:\OgreSDK\ogre\Components\Volume\include" "C:\OgreSDK\include\OGRE\Volume"

xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\BSPSceneManager\include" "C:\OgreSDK\include\OGRE\Plugins\BSPSceneManager"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\CgProgramManager\include" "C:\OgreSDK\include\OGRE\Plugins\CgProgramManager"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\FreeImageCodec\include" "C:\OgreSDK\include\OGRE\Plugins\FreeImageCodec"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\OctreeSceneManager\include" "C:\OgreSDK\include\OGRE\Plugins\OctreeSceneManager"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\OctreeZone\include" "C:\OgreSDK\include\OGRE\Plugins\OctreeZone"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\ParticleFX\include" "C:\OgreSDK\include\OGRE\Plugins\ParticleFX"
xcopy /s /v /y "C:\OgreSDK\ogre\build\include\OgreParticleFXPrerequisites.h" "C:\OgreSDK\include\OGRE\Plugins\ParticleFX"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\PCZSceneManager\include" "C:\OgreSDK\include\OGRE\Plugins\PCZSceneManager"
xcopy /s /v /y "C:\OgreSDK\ogre\PlugIns\STBICodec\include" "C:\OgreSDK\include\OGRE\Plugins\STBICodec"

xcopy /s /v /y "C:\OgreSDK\ogre\RenderSystems\Direct3D9\include" "C:\OgreSDK\include\OGRE\RenderSystems\Direct3D9"
xcopy /s /v /y "C:\OgreSDK\ogre\RenderSystems\Direct3D11\include" "C:\OgreSDK\include\OGRE\RenderSystems\Direct3D11"
xcopy /s /v /y "C:\OgreSDK\ogre\RenderSystems\GL\include" "C:\OgreSDK\include\OGRE\RenderSystems\GL"
xcopy /s /v /y "C:\OgreSDK\ogre\RenderSystems\GL3Plus\include" "C:\OgreSDK\include\OGRE\RenderSystems\GL3Plus"



xcopy /s /v /y "C:\OgreSDK\ogre\build\Dependencies\include\zzip" "C:\OgreSDK\include\zzip"
xcopy /s /v /y "C:\OgreSDK\ogre\build\Dependencies\include\freetype2\ft2build.h" "C:\OgreSDK\include"
xcopy /s /v /y "C:\OgreSDK\ogre\build\Dependencies\include\zconf.h" "C:\OgreSDK\include"
xcopy /s /v /y "C:\OgreSDK\ogre\build\Dependencies\include\zlib.h" "C:\OgreSDK\include"

Then, to get those into my projects, I use this .bat file (in the same directory as the other one):
Filename: CopyToProjects.bat (but my version has a lot more projects that they get copied to)

Code: Select all

xcopy /s /v /y "C:\OgreSDK\bin\Codec_STBI_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\Codec_STBI.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\OgreMain_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\OgreMain.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\OgreMeshLodGenerator_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\OgreMeshLodGenerator.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\OgreOverlay_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\OgreOverlay.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\Plugin_OctreeSceneManager_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\Plugin_OctreeSceneManager.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\Plugin_ParticleFX_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\Plugin_ParticleFX.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\RenderSystem_Direct3D9_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\RenderSystem_Direct3D9.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\RenderSystem_Direct3D11_d.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\RenderSystem_Direct3D11.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

xcopy /s /v /y "C:\OgreSDK\bin\zlib.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Debug"
xcopy /s /v /y "C:\OgreSDK\bin\zlib.dll" "C:\Imagindar\Work\Imagindar\Code\Current\Release"

How do you decide between static and dynamic linking?

I use dynamic linking as you can see above with the .dll being copied to my project.
I have not even attempted to do static linking, as dynamic linking works fine, so I have really not thought about deciding it. :D

Do you use OGRE's plugins.cfg file?

Yes, I use the plugins.cfg file in the .exe file directory, mine looks like this:

Code: Select all

# Defines plugins to load

# Define plugin folder
PluginFolder=.

# Define plugins
Plugin=RenderSystem_Direct3D9
Plugin=RenderSystem_Direct3D11
Plugin=Plugin_OctreeSceneManager
Plugin=Plugin_ParticleFX
Plugin=Codec_STBI

Do you use OGRE's getConfigFilePath() or getWritablePath() to store settings?

I do not use getConfigFilePath/getWritablePath to store my settings, I use my own options file that I have created a system around to be able to handle it from an in-game options menu. It is just a simple .txt file that I load at startup and set to all systems, and that I save when something changes from the in-game options menu. Settings are simple and looks like this:

Code: Select all

m_EffectVolume = 10
m_MusicVolume = 0
m_MasterVolume = 30
m_MicrophoneVolume = 100
m_VoiceChatVolume = 100
m_ResolutionSetting = 0
m_ShadowTechnique = 1
m_NumberOfShadowTextures = 1
etc

But how do you handle this kind of stuff when you publish your game?

Do you use an installer?

I do use an installer for standalone versions of the game, and that is through Inno Setup, and I make sure to install the Direct3D9 runtime (otherwise some computers fail to compile shaders, through dxwebsetup.exe from Microsoft) and the vcredist file for the Visual Studio C++ version that I am using (Microsoft Visual C++ 2017 64-bit).
That installer only creates a launcher of my game, and that launcher handles updates of the game automatically, which means that the installer is pretty small (around 50mb) even though the game can be dynamically large after the launcher has updated the game (around 700mb currently).
That launcher took a long time to do and I would not recommend doing one.
Why is because even if my launcher works perfectly, it is not as scalable as Steam or Itch would handle it.
If 10000 players suddenly download my standalone game and start the launcher, it would become a bottleneck to my website and they would completely stall the downloader because of that. I could potentially host the files on other servers that has infinite speed, but why would I when I can just host it on Steam or Itch?
In short, do not go the standalone launcher way.

If you use Steam (as a demo of the game only, do not release it since then you miss Next Fest for completely free marketing), or Itch, you can upload it there and it will handle everything instead.
And to be frank, that is what you should do, since Itch and Steam do not just handle the installing of the game, but it also makes it easier for players to find and play your game than a standalone version would be able to do.

I handle this through a program that I have made that I call "NewVersion".
It is just a simple C# WPF program that in an UI shows all steps that I need to go through to upload the game to all places needed, and why it is a program instead of just a checklist is because it can help me in certain ways that a checklist could not (for example, finding all files needed for end-game users and copying/zipping them to work for individual game stores, generating the next version number automatically, preparing a patch note automatically, opening links to webpages or programs like FileZilla and Inno Setup automatically, etc).
Through that "checklist" program, I get the game published as a standalone with Inno Setup on my own website, to Itch and to Steam.

Setting up a Steam page costs $100 and it takes a loooong time to actually get it working (it took me around 5 days of work).
Setting up an Itch page is free and it took me around 5 hours in total to do.

Uploading to Steam is simply by just zipping the contents and then just upload it.
For Itch, you just need one additional step, before zipping the contents you need to create a new file in that directory, and for me it looks like this:
Filename: .itch.toml

Code: Select all

[[actions]]
name = "play"
path = "Imagindar/Code/Current/Release/Imagindar.exe"

[[prereqs]]
name = "vcredist-2017-x64"

[[prereqs]]
name = "dx-june-2010"

That file basically just means that it is a game that you can play, where the .exe file is actually located in the directory structure, and the vcredist and Direct3D9 required (it automatically handles them from just their strings, you won't have to supply those files).
The same thing for Steam happens on the store page itself, which you need to just specify once and not each time you upload a new version of the game.

chilly willy
Halfling
Posts: 65
Joined: Tue Jun 02, 2020 4:11 am
x 19

Re: Help debugging failed assert( msSingleton );

Post by chilly willy »

rpgplayerrobin, thank you very much for all the detailed information. I appreciate you taking the time to write it all down for me. It will be my handbook when I am ready to publish and I appreciate the advice about Steam and Itch.

chilly willy
Halfling
Posts: 65
Joined: Tue Jun 02, 2020 4:11 am
x 19

Re: Help debugging failed assert( msSingleton );

Post by chilly willy »

I've been working on this all weekend and I got everything working again (but I have a question...)

As far as the original question (failing the singleton assert) I realized that even though I was deleting my build folder and building from scratch each time, XCode was caching some build results in its own folder somewhere which I probably forgot to tell it to clean. So what you said, paroj, about ABI makes sense.

For my second issue (getting all the libraries in one folder), I was confusing myself by going back and forth between Frameworks and dylibs and changing my PluginFolder and forgetting what it used to be. Don't drink and code.

I do have one question though. I originally built OgreOggSound when I was using OGRE 13.3. Since then I upgraded OGRE to 13.4, and then 14.0. I did not rebuild OgreOggSound and it continued to work. I may have gotten lucky about the ABI situation, but also OgreOggSound did not complain about not being able to find the OGRE library it was built for (I always delete previous version when I build). This weekend I rebuilt OgreOggSound for OGRE 14.0 and it worked but when I upgraded to OGRE 14.1, OgreOggSound threw this error:

Code: Select all

dyld: Library not loaded: @rpath/Ogre.framework/Versions/14.0/Ogre
  Referenced from: /usr/local/lib/libOgreOggSound_d.dylib
  Reason: image not found

I rebuilt OgreOggSound for OGRE 14.1 and it now works. How did OgreOggSound used to continue to work when I upgraded OGRE and deleted the previous version of OGRE but did not rebuild OgreOggSound?

Last edited by chilly willy on Mon Sep 18, 2023 6:37 am, edited 1 time in total.
chilly willy
Halfling
Posts: 65
Joined: Tue Jun 02, 2020 4:11 am
x 19

Re: Help debugging failed assert( msSingleton );

Post by chilly willy »

This may help figure it out. I've noticed something else different from before and now concerning OgreOggSound.

Before, on projects that used OgreOggSound, whenever I tried to run a program that was already fully compiled, XCode would complain about cyclical dependencies or something and fail. But if I just changed one character in the code and changed it back, XCode would recompile, rebuild, and run with no problems. I figured this was just some XCode bug. Now that I have rebuilt OgreOggSound, and now that it complains when it can't find the OGRE version it was compiled for, I no longer get the cyclical dependencies error, and I can run an already compiled program without having to force a recompile. This is a good thing and I am happy, but I would like to understand, if anybody has any idea what was happening, and what has changed.

Thank you as always for your help.

paroj
OGRE Team Member
OGRE Team Member
Posts: 2108
Joined: Sun Mar 30, 2014 2:51 pm
x 1134

Re: Help debugging failed assert( msSingleton );

Post by paroj »

my guess would be that you built OgreOggSound against Ogre dynlib which you either forgot to delete or that was ABI compatible by chance.

Note that even with going from 13.6 to 14.0 there is some ABI compatibility. I.e. if none of the functions that are listed here are used, you can just replace the dynlib:
https://ogrecave.github.io/ogre/abi_tra ... blems_High

the details in the link above also give you a feel for what does and does not break ABI