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

Author Topic: Application Crash With RenderWindow Instantiation  (Read 3206 times)

0 Members and 1 Guest are viewing this topic.

jmcmorris

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Application Crash With RenderWindow Instantiation
« on: September 08, 2013, 07:19:12 pm »
Hello, I am currently trying to debug an issue where instantiating a new sf::RenderWindow() results in a crash.

Quote
The thread tried to read from or write to a virtual address for which it does not have the appropriate access.

I have several hundred testers and only one person is running into this issue. This tester has a ATI mobility radeon HD 5870 graphics card, which has OpenGL 3.1 compatibility. Here is the stacktrace I got with a debug build.

Quote
atioglxx.dll!6903b212()
[Frames below may be incorrect and/or missing, no symbols loaded for atioglxx.dll]
atioglxx.dll!6903a73c()
opengl32.dll!_wglCbGetDdHandle@4()
opengl32.dll!_wglCbGetDdHandle@4()
opengl32.dll!_pgldrvGetPrimaryDriver@4()
opengl32.dll!___DescribePrimaryPixelFormat@16()
opengl32.dll!_wglNumHardwareFormats@20()
opengl32.dll!_wglDescribePixelFormat@16()
opengl32.dll!_wglChoosePixelFormat@8()
gdi32.dll!_ChoosePixelFormat@8()
crea.exe!sf::priv::WglContext::createContext(class sf::priv::WglContext *,unsigned int,struct sf::ContextSettings const &)
crea.exe!sf::priv::WglContext::WglContext(class sf::priv::WglContext *)
crea.exe!sf::priv::GlContext::globalInit(void)
crea.exe!sf::GlResource::GlResource(void)
crea.exe!sf::Window::Window(void)
crea.exe!sf::RenderWindow::RenderWindow(void)
crea.exe!boost::make_shared<sf::RenderWindow>() Line 134
crea.exe!sg::RenderSystem::RenderSystem(const bool createWindow) Line 36
crea.exe!boost::make_shared<sg::RenderSystem,bool>(bool && a1) Line 214
crea.exe!sg::GameManager::initialize() Line 109
crea.exe!main(int argc, char * * argv) Line 101
crea.exe!_WinMain@16()
crea.exe!__tmainCRTStartup() Line 547
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!___RtlUserThreadStart@8()
ntdll.dll!__RtlUserThreadStart@8()

Another thing to note is that sfml has not written anything to sf::err().

Any help would be greatly appreciated. I'm uncertain what the next step would be to try to resolve this.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Application Crash With RenderWindow Instantiation
« Reply #1 on: September 08, 2013, 09:23:48 pm »
ATI/AMD drivers are probably among the buggiest/quirkiest out there. It is a black art to determine which version will or will not fix the problem, but chances are, "problems" that they deem important will be fixed in newer driver releases. Software errors might also be a result of a hardware error. This has happened to me before, and in that case, your tester is out of luck. They could try (if brave enough) to install a Linux system side-by-side and test there to definitely rule out hardware failure, but more often than not the hardware is not the cause of the problem. However when 1 out of 100s of testers experience it, it is still a possibility.

I don't want to dive into another style debate, but is it really necessary to contain your RenderWindow inside a shared_ptr? I don't know the exact specifics of the implementation you are using (some boost implementation), but a possibility is that when invoking make_shared, the allocator for some reason might jump into another thread and do its magic there which might make the over-sensitive ATI/AMD driver blow up. Who knows... too many blackboxes... too little help from the developers of the drivers/OS... indie game developers are normally out of luck in these scenarios.

You could break in the sf::priv::WglContext::createContext(...) method and check to see if you are still inside your main thread...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

jmcmorris

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Re: Application Crash With RenderWindow Instantiation
« Reply #2 on: September 09, 2013, 06:29:53 pm »
Thanks for the reply binary.

I made an exe with just the example from http://www.sfml-dev.org/tutorials/2.0/graphics-draw.php and the tester still encounters this issue. This is likely a driver issue; however, could it be the case that SFML's createContext() could do something else to work around this? I'm thinking something like changing the descriptor that is provided to ChoosePixelFormat().

Alzurana

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Application Crash With RenderWindow Instantiation
« Reply #3 on: September 24, 2014, 07:44:43 pm »
Hey there,
well I had the exact same problem and it is caused by a race condition on AMD/ATI cards.
My engine has 3 threads, one main thread, one resource thread and one rendering thread.
Whenever 2 threads tried to create a texture or open a window at the same time I got this exact segmentation fault.
Same stack trace within the SFML, crash in atioglxx.dll
And no SFML error, because the runtime kills this nasty one before it lays any eggs.

So what causes this:
Apparently it's simply caused by 2 threads accessing oGL at the same time, from the same process ID.
It's a race condition, since it's not happening on all systems. I think a unique software/hardware combination causes this. Also, most systems don't crash on a simultaneous access.
You can easily prevent this by securing any call of createTexture and createRenderWindow with a mutex, and I would recommend to do so.
This bug is so unique that AMD probably won't fix it in the near future.

^ So if anyone needs a fix for that, ever.. There you have it!

Have a nice day <3


PS: This was my stack trace
The top function is a typical windows mask, don't get confused by it...
#0  55B55D40 atioglxx!DrvGetProcAddress                ()
#1  6E184ED2 sf::priv::WglContext::createContext       (this=0x7853d8, shared=0x787628, bitsPerPixel=32, settings=...)
#2  6E1842A4 sf::priv::WglContext::WglContext          (this=0x7853d8, shared=0x787628, settings=..., owner=0x784b40, bitsPerPixel=32)
#3  6E181ABC sf::priv::GlContext::create               (settings=..., owner=0x784b40, bitsPerPixel=32)
#4  6E182F92 sf::Window::create                        (this=0x787958, mode=..., title=..., style=5, settings=...)
#5  68ED6346 sf::RenderWindow::RenderWindow            (this=0x787958, mode=..., title=..., style=5, settings=...)
#6  00405BAD _JADE_internal::_cRenderWindow::InitWindow(this=0x783ea4, oNEW_VID_MODE=..., iSTYLE=@0x784304: 5)
#7  00404941 cGraphics::Run                            (this=0x783d60)
#8  0040BA61 _ThreadMainLoop                           (pParam=0x7842ec)
#9  76CD338A KERNEL32!BaseCleanupAppcompatCacheSupport ()
#10 026DFFD4 ??                                        ()
#11 77359F72 ntdll!RtlpNtSetValueKey                   ()
#12 007842EC ??                                        ()
#13 77359F45 ntdll!RtlpNtSetValueKey                   ()
#14 0040BA3C cThread::Run                              (this=0x77359f45 <ntdll!RtlpNtSetValueKey+1432>)
#15 007842EC ??                                        ()
#16 ??       ??                                        ()
 

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Application Crash With RenderWindow Instantiation
« Reply #4 on: September 26, 2014, 07:54:32 pm »
Yeah... I can confirm simultaneous access to the driver crashes on AMD.

The following code easily reproduces the issue when using AMD hardware:
#include <SFML/Graphics.hpp>
#include <deque>
#include <iostream>

void threadFunc(int i)
{
    sf::Context context;

    std::cout << "Context " << i << " created.\n";

    for (;;)
    {
        sf::Texture texture;
        texture.create(100, 100);
    }
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(200, 200), "Test");

    std::deque<sf::Thread*> threads;

    for (int i = 0; i < 40; i++)
    {
        threads.push_back(new sf::Thread(threadFunc, i));
        threads.back()->launch();
    }

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
        window.display();
    }

    while (!threads.empty())
    {
        threads.front()->terminate();
        delete threads.front();
        threads.pop_front();
    }
}
Just let it run a few times if you were (un-)lucky, since this is caused by a race condition.

The problem I guess... is that AMD didn't think about synchronizing wgl and pixel format operations inside their driver. If 2 threads simultaneously access any wgl function or GDI pixel format function (which just forwards to the driver anyway), it will crash somewhere inside the driver. I inserted locks around all context operations in the gl_dev branch and the problem seems to have disappeared.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).