Crash on shutdown when rendering sf::Text with default font #59

Closed
Oberon00 opened this Issue Jun 14, 2011 · 10 comments

Projects

None yet

6 participants

@Oberon00

I have Windows 7 x64, Ati Radeon 5650 (Mobile) and Visual Studio 2010. SFML revision (or last commit) is d497401 (the latest at the time I am writing this).

Consider the following code:

//#define NO_CRASH

#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

#ifdef NO_CRASH
#   include <SFML/Graphics/Font.hpp>
#endif

int main()
{
    sf::RenderWindow win(sf::VideoMode(800, 600), "Test");
#ifdef NO_CRASH
    sf::Font fnt;
    fnt.LoadFromFile("C:/Windows/Fonts/Arial.ttf"); // Change path if necessary
#endif
    sf::Text txt("Test");
#ifdef NO_CRASH
    txt.SetFont(fnt);
#endif
    win.Draw(txt);  // Without drawing, no crash occurs
}

Any program will crash when the SFML default font is used and the text is drawn to the window.
The crash happens at exit, in GlResource.cpp, Line 80 at the end of the Destructor of GlResource.
Error is: exception at 0x690974c4 in sf-crash.exe: 0xC0000005: Access violation reading location 0x00000008. It seems to be an a problem with a null pointer (location is 0 + offset of a member(?)).
Callstack was:

atioglxx.dll!690974c4()     
[Frames below may be incorrect and/or missing, no symbols loaded for atioglxx.dll]  
kernel32.dll!_HeapFree@12()  + 0x14 bytes   
atioglxx.dll!690852f4()     
atioglxx.dll!690a2c99()     
atioglxx.dll!697c7c80()     
sfml-window-d-2.dll!sf::GlResource::~GlResource()  Line 80  C++
sfml-graphics-d-2.dll!sf::Image::~Image()  Line 92 + 0x1e bytes C++
sfml-graphics-d-2.dll!sf::Font::Page::~Page()  + 0x4e bytes C++
sfml-graphics-d-2.dll!std::_Pair_base::~_Pair_base()  + 0x19 bytes  C++
sfml-graphics-d-2.dll!std::pair::~pair()  + 0x16 bytes  C++
sfml-graphics-d-2.dll!std::pair::`scalar deleting destructor'()  + 0x16 bytes   C++
sfml-graphics-d-2.dll!std::_Destroy >(std::pair * _Ptr)  Line 64  C++
sfml-graphics-d-2.dll!std::allocator >::destroy(std::pair * _Ptr)  Line 213 + 0x9 bytes   C++
sfml-graphics-d-2.dll!std::_Dest_val >,std::pair >(std::allocator > & _Alval, std::pair * _Pdest)  Line 288  C++
sfml-graphics-d-2.dll!std::_Tree,std::allocator >,0> >::_Erase(std::_Tree_nod,std::allocator >,0> >::_Node * _Rootnode)  Line 1617 + 0x22 bytes C++
sfml-graphics-d-2.dll!std::_Tree,std::allocator >,0> >::clear()  Line 1416  C++
sfml-graphics-d-2.dll!sf::Font::Cleanup()  Line 298 C++
sfml-graphics-d-2.dll!sf::Font::~Font()  Line 70    C++
sfml-graphics-d-2.dll!`sf::Font::GetDefaultFont'::`2'::`dynamic atexit destructor for 'font''()  + 0xd bytes    C++
sfml-graphics-d-2.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 415 C
sfml-graphics-d-2.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 526 + 0x11 bytes  C
sfml-graphics-d-2.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 476 + 0x11 bytes   C
ntdll.dll!_LdrpCallInitRoutine@16()  + 0x14 bytes   
ntdll.dll!_LdrShutdownProcess@0()  + 0x141 bytes    
ntdll.dll!_RtlExitUserProcess@4()  + 0x74 bytes 
kernel32.dll!76407a25()     
msvcr100d.dll!___crtExitProcess()  + 0x1b bytes 
msvcr100d.dll!___freeCrtMemory()  + 0x317 bytes 
msvcr100d.dll!_exit()  + 0x12 bytes 
sf-crash.exe!__tmainCRTStartup()  Line 568  C
sf-crash.exe!WinMainCRTStartup()  Line 371  C
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    
@Groogy

If you add a call to Display for the window does it work then? Just wondering. Still not good behavior.
It works for me though I do display and I don't have the same drivers.

@LaurentGomila
Simple and Fast Multimedia Library member

It's a known bug, I thought there was already a task for this. Anyway, the forum is full of messages about it.

@coolhome

Not sure if this will help but it only crashes if you close via a window. If you have a console and close through that there is no problem.

@retep998

Closing through the console is akin to simply calling exit(randomnumber) thereby avoiding all sfml cleanup functions so you don't get any errors.

@Oberon00

After reading this and (more important) this thread I tried something new.
First, I downloaded and compiled the latest development version and now I get a different crash for the old program: see http://pastebin.com/Fv5kgsMz.
However much more interesting is the following observation:
Crash (as before, same stacktrace):

#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

int main()
{
    sf::RenderWindow win(sf::VideoMode(800, 600), "Test");
    sf::Text txt("Test");
    win.Draw(txt);  // Without drawing, no crash occurs, as before
}

Crash (same as above):

#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Font.hpp>

int main()
{
    sf::RenderWindow win(sf::VideoMode(800, 600), "Test");
    sf::Text txt("Test", sf::Font::GetDefaultFont()); // Note the explicit GetDefaultFont() here.
    win.Draw(txt);
}

No crash:

#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Font.hpp>

int main()
{
    sf::RenderWindow win(sf::VideoMode(800, 600), "Test");
    sf::Font fnt(sf::Font::GetDefaultFont()); // <--------------------------
    sf::Text txt("Test", fnt); // If I don't pass fnt to constructor and don't set it via SetFont() it also crashes.
    win.Draw(txt);
}

If I move the line which defines the font before the RenderWindow, no crash occurs either.

This is clearly related to construction/destruction order (destruction order is the reversed construction order).
See also http://stackoverflow.com/questions/469597/destruction-order-of-static-objects-in-c and (more important) http://stackoverflow.com/questions/335369/finding-c-static-initialization-order-problems.

EDIT: Fixed markdown

EDIT2: When I explicitly call sf::Font::GetDefaultFont() before the construction of the text (in the original crashing program), I have a different callstack, when it crashes:

int main()
{
    sf::Font::GetDefaultFont();
    sf::RenderWindow win(sf::VideoMode(800, 600), "Test");
    sf::Text txt("Test");
    win.Draw(txt);  // Without drawing, no crash occurs
}

leads to

    atioglxx.dll!698bd4cf()     
    [Frames below may be incorrect and/or missing, no symbols loaded for atioglxx.dll]  
    atioglxx.dll!698c9079()     
    atioglxx.dll!6937baac()     
    msvcr100d.dll!___freeCrtMemory()  + 0x317 bytes 
    msvcr100d.dll!_exit()  + 0x12 bytes 
    fontcrash.exe!__tmainCRTStartup()  Line 568 C
    fontcrash.exe!WinMainCRTStartup()  Line 371 C
    kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
    ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
    ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    
@Oberon00

Maybe the problem could be solved by letting the user manage the lifetime of the default font and providing a method void setDefaultFont(Font&) which would then keep only a reference to the font. This has the additional advantage of letting the user set a custom font as default. To keep the simplicity of a builtin font, a method Font createDefaultFont() could be provided.

@Inverness

I'm also getting a crash with SFML.Net on exit in atioglxx.dll. Unfortunately it's not giving me a call stack so I can't provide it. I assume it is caused by this same issue. I believe the user needs a way to manage the lifetime of the default font as Oberon is suggesting. Doing otherwise seems to be too problematic.

Edit: So far the order of operations doesn't seem to affect whether or not it crashes. Even if I do Font.DefaultFont.Dispose() it still crashes. (I don't know whether this is even doing what I want)

Should I open a separate issue for this in the SFML.net repo?

Edit 2: Okay I've narrowed down the issue, going to open a ticket on the other repo.

@LaurentGomila
Simple and Fast Multimedia Library member

going to open a ticket on the other repo

You don't need to, it's most likely the same issue.

@Inverness

Too late, already made it: SFML/SFML.Net#11

The issue seems to involve the constructor for the Text class, so its not quite the same.

Edit: I reviewed the cases and figured that it happens whenver you set a Text string before setting the font, which is what happens in the constructor in certain cases. So it seems I just have to make sure a non-default font is specified before I set the display string and no crash will happen.

@LaurentGomila
Simple and Fast Multimedia Library member

Solved by removing the default font in commit a0c1f5f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment