Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Exception raised on exit. Using singleton with SFML 2.0.  (Read 3777 times)

0 Members and 1 Guest are viewing this topic.

soy_yuma

  • Newbie
  • *
  • Posts: 4
  • Game developer & science lover!
    • View Profile
    • My personal webpage
Exception raised on exit. Using singleton with SFML 2.0.
« on: April 13, 2013, 12:54:33 am »
Hi there! First post here :-)

I've found this curious situation in which you get an exception on program exit when your main RenderWindow is a static object (in my case is a singleton). The exception is thrown when I close the window and the corresponding stack trace goes like:

Quote
   nvoglv64.dll!000000005e1f9b74()   Unknown
   opengl32.dll!000007f967b49ac1()   Unknown
   sfml-window-d-2.dll!sf::priv::WglContext::~WglContext() Line 114   C++
   sfml-window-d-2.dll!sf::priv::WglContext::`scalar deleting destructor'(unsigned int)   C++
   sfml-window-d-2.dll!sf::priv::GlContext::globalCleanup() Line 119   C++
   sfml-window-d-2.dll!sf::GlResource::~GlResource() Line 75   C++
   sfml-window-d-2.dll!sf::Window::~Window() Line 77   C++
   sfml-graphics-d-2.dll!sf::RenderWindow::~RenderWindow() Line 61   C++
   grape++-d.dll!Grape::Application::~Application() Line 49   C++

I'm using SFML 2.0, not from the RC but from the revision a40ef79a18b16fe47ce7eecb7a8d8f6b42b9e5d0 of Feb 21 20:25:11 2013 +0100 compiled with Visual C++ 2012 Express for Desktop to x64 architecture. SFML is linked into a dynamic library, which is also linked (dynamically) to the Application code. The Application is a Windows application (using /SUBSYSTEM:WINDOWS) so its entry point is WinMain, but WinMain just calls a generic int main(int, char**).

I'm not sure, but possibly this exception is related to this other forum thread I didn't want to revive:
Possible Bug in RenderWindow Destructor (SFML 2.0)

I haven't found recent information about this "bug" (inconvenient situation?) so I wanted to ask you how do you avoid it. Also whether it's related to the other forum thread or not. Maybe it's just I'm doing something wrong...

Well, I found an ugly and partial solution. Looks like this happens because SFML deallocates some global resources (OpenGL context?) that can't be postponed to the destructor of a static instance of a class. So I created a destroyInstance() method in my Application singleton that simply deletes the single instance. This prevents the exception on exit.

Relevant code looks like:
// in main.cpp
int main(int argc, char *argv[])
{
        // Application initialization and main loop.
        Grape::Application::instance()->init();
        Grape::Application::instance()->loop();

        // Application destruction before end of main.
        Grape::Application::destroyInstance();
}

// in Application.h
class Application: public sf::RenderWindow
{
public:
        GRAPE_API static boost::shared_ptr<Application> instance(void);
        GRAPE_API static void destroyInstance(void);
private:
        static boost::shared_ptr<Application> sInstance;
};

// in Application.cpp
boost::shared_ptr<Application> Application::sInstance;

boost::shared_ptr<Application> Application::instance(void)
{
        if(!sInstance)
        {
                sInstance = boost::shared_ptr<Application>(new Application());
        }
        return sInstance;
}

void Application::destroyInstance(void)
{
        if(sInstance)
        {
                sInstance.reset();
        }
}
 

What do you think about it? How do you prevent this situation (apart from avoiding singletons and static instances of classes)? Is it really that ugly what I'm doing?

Thanks for your insights! :-D

Álex

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10875
    • View Profile
    • development blog
    • Email
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #1 on: April 13, 2013, 01:13:00 am »
What do you think about it? How do you prevent this situation (apart from avoiding singletons and static instances of classes)? Is it really that ugly what I'm doing?
Yes it's ugly. Just don't use singletons, there's no reason for it and if you search the forum a bit you can read the discussions there for the why. Kinda don't feel like repeating it over and over and over again. ::)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

soy_yuma

  • Newbie
  • *
  • Posts: 4
  • Game developer & science lover!
    • View Profile
    • My personal webpage
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #2 on: April 13, 2013, 12:12:09 pm »
I've read a lot of discussions (even flame wars) on whether to use Singletons or not. I understand there are reasons against (example) and  for it (example). I didn't want to start with it again  ;D

What I was wondering is that if, assuming I have to use a Singleton for the WindowRendered (or better, without discussing whether that's a good design choice or not), there are better mechanisms for avoiding the "on exit exception".

soy_yuma

  • Newbie
  • *
  • Posts: 4
  • Game developer & science lover!
    • View Profile
    • My personal webpage
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #3 on: April 13, 2013, 12:22:04 pm »
Anyway, I just Googled in the forums for a solution (Am I the only one who can't search the forums?) and found out this:
program crashes on exit - reply #23

Looks like it's a known practice :D

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10875
    • View Profile
    • development blog
    • Email
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #4 on: April 13, 2013, 01:22:59 pm »
Looks like this happens because SFML deallocates some global resources (OpenGL context?) that can't be postponed to the destructor of a static instance of a class.
This is simply a C++ thing. The destruction order of global objects are undefined, which is another reason, why one shouldn't use global variables.

Am I the only one who can't search the forums?
You can, you just need to deselect some of the sub-forums, so the database doesn't hang-up on the SQL query (and Laurent should finally upgrade to a better hosting package...).

I understand there are reasons ... for it (example).
There isn't really one. I can guarantee you that with a good design you won't have any performance issue due to not using a singleton! Even if there are any cases where it might make sense, using it for sf::RenderWindow is not one of it.

What I was wondering is that if, assuming I have to use a Singleton for the WindowRendered (or better, without discussing whether that's a good design choice or not), there are better mechanisms for avoiding the "on exit exception".
Instantiate the global variable locally, so its destruction has a local scope and not a global one.

program crashes on exit - reply #23
Funny to see Nexus discussing about singletons... ;D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #5 on: April 13, 2013, 01:44:12 pm »
program crashes on exit - reply #23

Looks like it's a known practice :D
Don't quote it out of context. If you search my other posts, you'll find my actual opinion about singletons and global variables. In short: Don't use them.

In fact, there are exceptional cases where one can't avoid singletons. The problem is, when you say that, every beginner comes and thinks he has one of those cases. Which is hardly ever true, most people are just too lazy to think about clean design. You already see how ugly the implementation in the linked thread is. And if you read the thread a bit more precisely, you also see hints to problems it yields (allocation and deallocation, dependencies, undefined behavior). There are even more issues, just search my posts ;)

In conclusion, you pay an extremely high price for using global variables and singletons. Even if you think it's comfortable, there are a ton of disadvantages that you may not be aware of. Almost always it's possible to structure the design in a modular way, so that it works without global access. Please take the advice seriously and try an alternative implementation -- you won't regret it.

If you need input on how to design your code in a better way, don't hesitate to ask.
« Last Edit: April 13, 2013, 01:45:49 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

soy_yuma

  • Newbie
  • *
  • Posts: 4
  • Game developer & science lover!
    • View Profile
    • My personal webpage
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #6 on: April 13, 2013, 02:30:58 pm »
Thanks eXpl0it3er and Nexus for your advice. I've been using Singletons to speed up the game development process. I realize it's a bad practice, but for the small projects I'm involved in it usually works. Anyway I think now I feel comfortable enough with C++ to find better designs...

Quote from: Nexus
Don't quote it out of context. If you search my other posts, you'll find my actual opinion about singletons and global variables.

Sorry, I didn't want to take it as an example of you being supporter of the Singleton pattern. I just wanted to point out that the destroyInstance() in the singleton with global instance was already known in the forums  :-[

Quote from: Nexus
If you need input on how to design your code in a better way, don't hesitate to ask.

Thanks! I take your word  :P

But first I'll think about:
  • What components of my code use Singletons
  • How do implement such components without using Singletons
before posting anything about it. It's not fair saying "I don't have time to read how to stop using Singletons" and then ask you guys to do the dirty work for me :-)

So far I've found a gold mine! Don't focus on the topic title, but the links there posted. I think the message bus approach can fit my project and will considerably reduce the dependency tree!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Exception raised on exit. Using singleton with SFML 2.0.
« Reply #7 on: April 13, 2013, 02:39:43 pm »
Yes, these are advanced software architectures. The first step already begins when transforming your singleton into a normal class.
class Application
{
    public:
        Application();
        void run();

    private:
        ... // components
};

int main()
{
    Application app;
    app.run();
}

This will raise a lot of new questions, namely how to replace all the global accesses to the Application instance. Think about why these accesses are needed, and if it's not possible to pass the required data directly to the different components, instead of letting them ask for the data.

It takes some time to reflect about everything, but it's an interesting task :)
« Last Edit: April 13, 2013, 02:42:08 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: