Access Violation error in the destructor of sf::AudioDevice #30

Closed
fpoisson opened this Issue Apr 22, 2011 · 59 comments

Projects

None yet
@fpoisson

Access Violation error occurs int the destructor of sf::AudioDevice on Windows XP SP3. It doesn't occur on Windows 7 and Windows Vista.

Here is the instruction pointed by the visual C++ 2008 debugger:

Code:

AudioDevice::~AudioDevice() 
{ 
    // Destroy the context 
    alcMakeContextCurrent(NULL); 
    if (audioContext) 
=>           alcDestroyContext(audioContext); 

    // Destroy the device 
    if (audioDevice) 
        alcCloseDevice(audioDevice); 
} 

The error can be reproduced with this simple code :

#include <SFML/Audio.hpp> 

int main() 
{ 
    sf::Sound Sound; 

    return EXIT_SUCCESS; 
} 

This problem was first discussed in this post of the french forum :
http://www.sfml-dev.org/forum-fr/viewtopic.php?t=3443

@LaurentGomila
Member

Which version of SFML? Which libraries (dynamic or static)? Are you sure that you use the openal32.dll file provided in the extlibs/bin directory?

@fpoisson

I use the dll versions of this SFML2's revision :

  • Revision: ad79328
  • Date: 15/04/2011 18:14:35
  • Message: Fixed recursive mutex lock in GlContext::Cleanup()

I use the openal32.dll file provided in the extlibs/bin/x86/ directory.

@fpoisson

With the statics versions (debug & release), the error doesn't occur.

@LaurentGomila
Member

Ok, I know what's wrong. Thanks for your feedback.

@kevvo1288

I am having the same problem in Windows 7.
Steps:

  1. Generate project using Cmake
  2. Build all Projects in Visual Studio 2010 (32 bit, assume from now on)
  3. Try to run pong - Can't find SFML dlls.
  4. Add SFML debug dlls to directory.
  5. Try to run pong - Can't find openAL32.dll
  6. Add openAl and libsnd dlls to directory.
  7. Try to run pong - crashes on alcDestroyContext(audioContext); (in AudioDevice::~AudioDevice() )
  8. Add resources directory (I am slow but thorough :) )
  9. Try to run pong - IT WORKS!!! Game plays just fine, sound happens, etc...
  10. Press escape to quit pong - crashes on alcCloseDevice(audioDevice); (in AudioDevice::~AudioDevice() )

Same issue: It crashes in the deconstructor, although the exact line it fails on depends on whether or not the context has been created.

I'm free to experiment if there is a fix you'd like to try. I have the SFML git repo separate from the output from Cmake.

@LaurentGomila
Member

Thanks for your feedback. Like I said previously, I know what's wrong and I'll fix it soon.

@dvoid
dvoid commented Jun 13, 2011

been quiet here for a while, Any news about this bug? i really really need a fix as soon as possible. tanks

@LaurentGomila
Member

As you can see, it's planned for SFML 2.x, not 2.0. So it's not the top priority, sorry.

@gchatelet

Laurent can you explain a bit more on "Ok, I know what's wrong", so we can have a look and maybe submit a patch at some point ? I'm also running into this issue.

@LaurentGomila
Member

Yeah, it's simple: the AudioDevice instance is destroyed at global exit.

@yadurajiv

If I don't use the openal32.dll that came with sfml2, this error does not seem to happen. The latest OpenAL32.dll loads up slow, but it does not crash on exit.

@LaurentGomila
Member

The latest OpenAL32.dll loads up slow, but it does not crash on exit.

The latest OpenAL32.dll from where?

@LaurentGomila
Member

As far as I know, this version is not updated anymore.

Updated Summer 2009 : Version 2.0.7.0

@yadurajiv

hmm.. But strangely enough it works, for the time being. What codebase is the openal32 in the extlibs based on?

@LaurentGomila
Member

The only implementation that is maintained and used everywhere now is OpenAL-Soft.

@yadurajiv

yup, the binaries here - http://kcat.strangesoft.net/openal.html gives the error, which means we are back at square one _ sighs

@Ceylo
Contributor
Ceylo commented Apr 7, 2012

I've got a similar crash on Windows 7 but on alcCloseDevice(audioDevice); in my project (different code). The sample code provided here to reproduce the bug correctly produces alcDestroyContext() bug though.

However the 1.14 DLL provided at http://kcat.strangesoft.net/openal.html#download fixes both my crash and the one quoted in this issue (NB: in the readme they say the provided OpenAL binary isn't redistributable).

Note that the 1.14 release is 9 days old.

@matpow2
matpow2 commented Apr 12, 2012

Even with the 1.14 OpenAL-Soft DLL, I was getting crashes on Windows XP 32bit SP3. I managed to fix the issue by removing SFML's AudioDevice deconstructor. It seems like OpenAL-Soft uses an atexit deconstructor to clean up after itself, which is the case with SFML's AudioDevice deconstructor too. This probably leads to OpenAL/SFML trying to deinitialize stuff that's already been destroyed.

@GatorQue
GatorQue commented Jul 7, 2012

@matpow2
When I use 1.14 OpenAL-Soft DLL my crashes went away, perhaps you were picking up an older version somewhere else on your computer?

@germinolegrand

I have the same problem, with crashes very often. I can't wait any longer, any advice before i go and try to fix it myself ?

@germinolegrand germinolegrand added a commit to germinolegrand/SFML that referenced this issue Apr 10, 2013
@germinolegrand germinolegrand fix #30 audio context deletion
SFML#30 fixed
8315c60
@germinolegrand

The fix I did is actually a partial fix, there are no more crashes, but a lot of warnings in the console instead (not really a problem, but i don't like seeing warnings it means some errors might occur later). I will try to investigate later.

@LaurentGomila
Member

Until you fix your fix (the diff shows all the files being completely changed -- probably due to different line breaks), there's no way to know what you did...

@Oberon00
Contributor

You can append &w=1 to the commit URL to see only non-whitespace changes.

@LaurentGomila
Member

Rather ?w=1 since the commit URL has no other argument ;)

So according to what I see, you moved the AudioDevice class from private to public. How does that solve anything?

@germinolegrand

It permits to manualy close the device. But i know it's a really poor fix, but the only i had time to apply (random crashing due to audio device is not really good to find other bugs because you can never know if the bug is from your code or the audio device). According to the warnings I get, there are some troubles with the audio threads endings.

An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (232) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (221) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (232) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (221) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundStream.cpp (232) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state
An internal OpenAL call failed in SoundSource.cpp (181) : AL_INVALID_OPERATION,
the specified operation is not allowed in the current state

@ColinDuquesnoy

Hi,

I think I found a clean solution but it requires to manually call an extra function at the end of the program.

The problem is that the static globalDevice is destroyed at global exit. I made the globalDevice a pointer and added an uninitAL function which delete the globalDevice pointer. I manually call this function at the end of my program.

In ALCheck.cpp:

////////////////////////////////////////////////////////////
/// Make sure that OpenAL is initialized
////////////////////////////////////////////////////////////
AudioDevice* globalDevice = NULL;
void ensureALInit()
{
    // The audio device is instanciated on demand rather than at global startup,
    // which solves a lot of weird crashes and errors.
    // It must be manually destroyed because it is NOT fine to let it be destroyed at global exit
    if(globalDevice == NULL)
        globalDevice = new AudioDevice();
}

void unInitAL()
{
    if(globalDevice)
        delete globalDevice;
}

Maybe the best solution would be to let the user manage the audio device by himself?

// SFML/examples/sound/Sound.cpp
int main()
{
    sf::AudioDevice d;

    // Play a sound
    playSound();

    // Play a music
    playMusic();

    // Wait until the user presses 'enter' key
    std::cout << "Press enter to exit..." << std::endl;
    std::cin.ignore(10000, '\n');

    return EXIT_SUCCESS;
}
@LaurentGomila
Member

Things are more complicated.

I made the globalDevice a pointer and added an uninitAL function which delete the globalDevice pointer

This is not a robust solution. User may have audio instances in global scope, or as members of automatic variables, which would then be destroyed after the user call to unintAL().

Maybe the best solution would be to let the user manage the audio device by himself?

This also leads to more problems regarding audio instances that need the device to initialize or destroy themselves.

Of course, a more complicated solution could be elaborated based on that, and it might even be the only one, but my point is that it requires serious thinking to take in account all the problems, and everything that a potential solution would involve.

@germinolegrand

Having to call anything manually at delete time is dangerous (not exception-safe at all).

Letting the user instanciate the sf::AudioDevice adresses nearly every problems : if you need the risky thing of using audio in the global scope, then you only have to ensure sf::AudioDevice is instanciated before (and will be destroyed after), which is not much complicated if you control the whole thing (basically, put an sf::AudioDevice and the sf::Music you want as class members of the global in the right order).

But Laurent might be right, I tried this as a fix, and i still experiment some troubles. I guess I'll have to analyse the sfml-audio sources a bit more precisely...

Edit: crap, those multi-accounts really need some better support from github...

@ColinDuquesnoy

Tell me if I'm wrong but I think this issue (and also this one #464) is due to the way SFML initialise/de-initialise each subsystems. SFML is using lazy initialisation which makes the API easy to use for a newcomer but prevents more advanced user from controlling what happens behind the scene.

Most of the frameworks I've dealt with have some sort of explicit entry point for initialising/destroying a subsystem: this can be a pair of init/deinit function or a sort of Application class (think about QtCoreApplication, QtGuiApplication).

Maybe we could have something similar?

// SFML/examples/sound/Sound.cpp
int main()
{
    // init sub systems
    sf::WindowSystem windowSystem;  
    sf::AudioSystem audioSystem;

   // we can now start using sf::Window, sf::Sound,...
}

This implies a few restrictions, you cannot have global variables which depends on a specific subsystem and you must always declare such variables after the systems declarations.

Also I am not sure we have to worry about user's bad practices (global variables,...)

@LaurentGomila
Member

This is exactly the kind of evolution that I'm more and more seriously thinking about, and yes I'm worried about proper management of dependant resources declared at global scope.

@uUJsd7PX

I had this error on windows 7. After spending 1 day on this issue I found that it was caused by wrong .lib order. The order that worked for me is this:

#pragma comment(lib, "sfml-system-d.lib")
#pragma comment(lib, "sfml-main-d.lib")
#pragma comment(lib, "sfml-graphics-d.lib")
#pragma comment(lib, "sfml-window-d.lib")
#pragma comment(lib, "sfml-audio-d.lib")
#pragma comment(lib, "sfml-network-d.lib")

Same thing in VC case if you add them in Linker->Input->Additional Dependancies.

@retep998

Requiring that SFML libraries be loaded in a specific order is hardly an ideal solution, but at least we know the order is part of the problem.

@LaurentGomila
Member

No it is not caused by wrong libraries order. Neither is it a proper fix. It's just luck, and it may not even work for everyone.

@chrishaslehurst

Well, changing the library include order in the linker also worked for me. So seems like it is a fix Laurent.

@LaurentGomila
Member

No it's not ;)

@chrishaslehurst

It didn't work before, then it worked. Sounds like a fix to me!

@MarioLiebisch
Member

It's a temporary fix happening due to "pure luck" (actually it's less about luck and can be reproduced due to the deterministic nature of software, but that doesn't count). As far as I know the order in which libraries are linked can (but doesn't do so necessarily) influence the order of creation/destruction of static members and that's the problem here.

@retep998
retep998 commented Dec 8, 2013

The order of initialization for static variables is only defined within a single compilation unit. Order across multiple units is undefined, and as such code relying on this order is relying on undefined behavior.

@binary1248 binary1248 added a commit that referenced this issue May 18, 2014
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
9b52fb4
@binary1248 binary1248 added a commit that referenced this issue May 18, 2014
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
fc82932
@pmer pmer added a commit to DevelopersGuild/flappybird that referenced this issue Jun 10, 2014
@pmer pmer exit crash from SFML mismanagement of OAL context
SFML doesn't have a working, portable way of deinitializing the OpenAL
context it creates from playing sound files.  They have known about this
since 2011, as evidenced by
SFML/SFML#30.  Fortunately, somebody in
the comments section found a quick fix.

Switch the order in which the SFML libraries are linked.
a771d84
@binary1248 binary1248 added a commit that referenced this issue Jun 11, 2014
@binary1248 @TankOs binary1248 + TankOs Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
243bf95
@PatrickTorgerson

uUJsd7PX's fix worked for me, temporary, proper or otherwise I don't care, it still got the job done for the time being.

@manolismi

For me it didn't! This bug needs to be fixed soon, because every application that uses audio crashes! Hell, you can't distribute applications that crash! Because of mine application being fullscreen, when you click a button i made for closing the application, it freezes! The segmation error window pops behind the game and is not shown! And unless you click ok on it, the application can't close! But you can't click it because you don't see it! So reboot is the only option!

@manolismi

Anyways, is there something that I can do that fixes it? If yes, please explain. Thank you very much, SFML is great and it is a pity that this bug is harassing my first game experience.

@binary1248
Member

Use this experimental branch and see if it fixes the problem (it should). It might get merged at some point, but don't hold your breath.

@manolismi

Thanks for replying, can you explain to me though what exactly I need to do? Replace the files by the corresponding experimentals?

@binary1248
Member

Just download the zip and pretend you got it instead of the original SFML files. Of course you will have to build it yourself since there are no pre-compiled versions of branches.

@manolismi

I don't know how to build it! I read the tutorial building with cmake but I can't do it. I have mingw and dev c++ 5.6.3 IDE

@PatrickTorgerson

hey manolismi, I have a working build for codeblocks and visual studio express 2013, both of wich dont have this problem if you want to switch to one ill send you one.

@achpile
achpile commented Jun 23, 2014

binary1248, Thanks a lot!!! This branch really fixes this annoying bug!!! Can't wait to see this branch merged into master! =)

@mantognini
Member

@manolismi if you have a specific issue with cmake even after following 1:1 the tutorial and looking online for known solutions, you can ask for help on the forum (it's more appropriate there than here).

@manolismi

Binary1248 I'm so grateful for your branch! Everything works! I can't thank you enough everyone, for your kindness and being helpful and supportive, even though I've spammed you a lot.

@binary1248 binary1248 added a commit that referenced this issue Jul 4, 2014
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
dcc4f4e
@eXpl0it3r eXpl0it3r added the s:accepted label Jul 5, 2014
@binary1248 binary1248 added a commit that referenced this issue Jul 12, 2014
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
c7bb5da
@binary1248 binary1248 added a commit that referenced this issue Aug 28, 2014
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
6abfb53
@Ceylo
Contributor
Ceylo commented Sep 25, 2014

As binary1248 seems to have fixed the issue, is it considered resolved?

@LaurentGomila
Member

It's in a branch that is not merged (tested) yet, so no. It will be marked as resolved after being merged into master.

@Ceylo
Contributor
Ceylo commented Sep 25, 2014

Ok. I couldn't find on which branch the commit was :)

@ghost
ghost commented Oct 11, 2014

How much time will this take to get merged in master?
Got the same problem and it's kind of annoying...

@Bromeon
Member
Bromeon commented Oct 11, 2014

As you see the milestone is 2.x, meaning it will happen after SFML 2.2.

But why don't you use the bugfix/al_context branch until then? The more feedback we get, the faster things will progress ;)

@ghost
ghost commented Oct 11, 2014

That's what i'm going to do, but I'm still learning a lot in C++ basics, and had some problems using Cmake last time ( almost an afternoon to get SFML2.1 ), so i'm kind of affraid of trying it again !
No choice I guess ;)

EDIT: Downloaded and linked new libraries compiled from: https://github.com/LaurentGomila/SFML/tree/bugfix/al_context
Still have the exact same problem...
Even with only "sf::Sound sound;" in the main function the error still appears.
Only fix I found is using static linking

Some help would be greatly appreciated :)

@eXpl0it3r eXpl0it3r removed this from the 2.x milestone Nov 13, 2014
@fpoisson fpoisson removed this from the 2.x milestone Nov 13, 2014
@binary1248 binary1248 added a commit that closed this issue Jan 1, 2015
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
0ad401c
@binary1248 binary1248 closed this in 0ad401c Jan 1, 2015
@eXpl0it3r eXpl0it3r added this to the 2.3 milestone Jan 1, 2015
@vihanchaudhry vihanchaudhry referenced this issue in DevelopersGuild/wraithkeeperstomb May 27, 2015
Closed

Sound crash #69

@eXpl0it3r eXpl0it3r pushed a commit to eXpl0it3r/SFML that referenced this issue Sep 10, 2015
@binary1248 binary1248 Made OpenAL context management more intelligent, in analogy to OpenGL…
… context management. OpenAL contexts now only exist as long as AlResources require them and are destroyed when they are no longer required. Fixes #30.
a1dd8f9
@zedfax
zedfax commented Feb 13, 2016

I've just compiled SFML from master and same problem, my programm exit with value "-1 073 741 515")

@zsbzsb
Member
zsbzsb commented Feb 14, 2016

@zedfax Please open a thread on the forum as I kinda doubt this is your issue.

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