SFML community forums

Help => Graphics => Topic started by: jwezorek on November 13, 2017, 10:16:45 pm

Title: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: jwezorek on November 13, 2017, 10:16:45 pm
I'm seeing an illegal access exception at shutdown of the application in which a desctructor is trying to destroy an sf::Texture in sfml 2.4.2. The same code compiles to an application that shuts down with no exception in against 2.4.1. The relevant part of the stack looks like the following:

demo.exe!sf::priv::GlContext::acquireTransientContext(void)
demo.exe!sf::GlResource::TransientContextLock::TransientContextLock(void)
demo.exe!sf::Texture::~Texture(void)

Joe
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: eXpl0it3r on November 13, 2017, 10:28:45 pm
And what's the relevant code? Remember if it's really an SFML issue, the problem can be reproduced in a minimal example with less than 100 lines of code.
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: Laurent on November 13, 2017, 10:36:24 pm
Is this destruction happening at global exit (ie. is your sf::Texture static or declared in global scope)?
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: jwezorek on November 13, 2017, 11:09:11 pm
It's wrapped in a shared_ptr. I can whittle it down to small example but will take some time.
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: jwezorek on November 14, 2017, 12:42:41 am
Actually I take that back -- the texture in question is ultimately owned by a static/global  that will be destroyed by the application terminating, and if I make it not a static/global the error does not occur.
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: jwezorek on November 14, 2017, 01:25:40 am
Okay on Windows built with vs 2015, with the image file being valid, the following throws on closing the window in 2.4.2 but not in 2.4.1. If you move the declaration of game into the main function it is fine.


#include <memory>
#include <Windows.h>
#include <SFML/Graphics.hpp>

class Scene
{
   std::shared_ptr<sf::Texture> bkgd_tex_;

public:

   Scene::Scene()
   {
   }

   void Scene::setBackground(const std::shared_ptr<sf::Texture>& tex)
   {
      bkgd_tex_ = tex;
   }
};

class Game
{
private:
   std::unique_ptr<sf::RenderWindow> window_;
   std::shared_ptr<Scene> active_scene_;

public:

   Game() {
   }

   void initialize()
   {
      sf::VideoMode video_mode;
      unsigned int style;
      video_mode = sf::VideoMode(600, 600);
      style = sf::Style::Titlebar | sf::Style::Close;

      window_ = std::make_unique<sf::RenderWindow>(video_mode, "foo", style);
   }


   void run(const std::shared_ptr<Scene>& startingScene)  {
      active_scene_ = startingScene;
      sf::Event event;
      while (window_->isOpen()) {
         while (window_->pollEvent(event)) {
            if (event.type == sf::Event::EventType::Closed)
               window_->close();
         }
      }
   }
};

Game game;

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

   game.initialize();
   auto scene = std::make_shared<Scene>();
   auto bkgd = std::make_shared<sf::Texture>();
   bkgd->loadFromFile(".\\data\\escher_square.png");
   scene->setBackground(bkgd);
   game.run(scene);

   return 0;
}
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: Laurent on November 14, 2017, 06:36:04 am
Some SFML classes rely (directly or indirectly) on global variables, and since the order of destruction of globals across translation units is undefined, you have undefined behavior when you destroy such classes at global scope.

Don't let SFML objects (espacially resources like sf::Texture) be constructed/destroyed at global scope, and everything will be fine.
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: jwezorek on November 14, 2017, 05:48:02 pm
Don't let SFML objects (espacially resources like sf::Texture) be constructed/destroyed at global scope, and everything will be fine.

Okay, thanks that is not a hard change to make; however, I understand the order of destruction here is undefined, but couldnt the implementation do something akin to reference counting to keep arbitrary destruction orders from throwing exceptions?
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: achpile on November 14, 2017, 05:55:47 pm
you can use new and delete to manage the order.
Title: Re: unhandled exception in sfml 2.4.2 but not 2.4.1
Post by: eXpl0it3r on November 14, 2017, 06:23:22 pm
We already do reference counting for certain things, but that doesn't prevent destruction order issues. Your globally initialized object references the globally initialized SFML resource, so the reference count for the resource is 1, but the the destructor of the SFML resources is called, leaving a dangling reference in your object.