-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash after closing wxWidgets with SFML-window #1549
Comments
I pinged @mantognini already based on your forum post, as he'd know best what is going on here. I tried to understand it, but I don't really following the whole logic and workarounds... |
I quickly looked into it.
Is wx corrupting pthread state? The crash happens in
Maybe someone more familiar with wx could help? |
Separating the multiple inheritance of wxSfmlCanvas is something I would like to try in the coming weeks. Because maybe this crash is caused by destructing the wx stuff prior to the sfml::window? After a second thought, maybe switching the order of the inheritance could yield different results? Another approach, I would like to try is rolling back wxWidgets to an earlier version, such as 2.8.12. Maybe this approach could work for now until this one is resolved later? I will let you know what I find in the coming weeks. In advanced, thank you for your patience and help. -James Harris |
As expected, the objects destruction order doesn't matter. As a result, reversing the inheritance had no impact. For the second test, I tried separating the inheritance to isolate this issue to the NSView. So, I made sf::RenderWindow into a member of wxSfmlCanvas. Interesting enough, after closing the application, the debug console now outputs the following message.
It appears that the NSView is being closed before SFML has a chance to shutdown, I think. So, my next test will be to wrap sf::RenderWindow into a singleton class to isolate wx. I'm suspecting wx is closing the NSView while SFML is still using it, possibly releasing resources too soon. -James Harris |
I wrapped sf::RenderWindow into the singleton class, and I was able to isolate the shutdown routines to run three tests. Shutdown SFML before wx didn't stop the crash from occurring, but instead caused a 'invalid or prematurely-freed autorelease pool' during wx's shutdown. If wx was allowed to shutdown completely while sf::RenderWindow is wrapped in a singleton class the crash also still occurred. The final test actually eliminated the crash and implies a problem with compiler destructor priority between NSView and SFML. For the last test, I took out the singleton, and declared sf::RenderWindow as a global variable wrapped inside a namespace. Long behold, the application stopped crashing after closing the application. Somewhere in the operating system's shutdown process the destructor order is off. To conclude, adding attribute((destructor[(priority)])) function attributes could be a possible solution. |
Would that be an SFML modification or one in your own code? |
This would be a modification to SFML, but I would like to take back my statement about using attribute. After further research today into what NSAutoreleasePool is doing. I found this resource which may help bkaradzic/bgfx#1607 . There may be an issue with NSAutoreleasePool and how SFML'd usage is interfering with wx on a single thread. The resource says it appears to work on multi-thread. Their solution was to move NSAutoreleasePool to another location to prevent conflicts. |
GUI toolkits such as wxWidgets and Qt provide their own NSAutoreleasePool objects. To avoid pool corruption, it is required that the pools be nested, which the previous implementation did not guarantee. Furthermore, autorelease pools should always be drained in the same context (function, loop, etc.) that they are created, which was not the case with the previous implementation (https://developer.apple.com/documentation/foundation/nsautoreleasepool). This commit complete removes the AutoreleasePoolWrapper, and functions that use autorelease create and drain their own pools. Should fix crashes in issue SFML#1549 and similar.
The issue here is that SFML's handling of
What SFML does is it creates a This violates the above guideline from Apple's documentation, and can result in a situation where there are multiple non-nested autorelease pools especially when interfacing with other GUI libraries (multiple nested autorelease pools are fine). This is what I believe is happening in the case of wxWidgets. wxWidgets creates its own autorelease pools during the event loop (after SFML creates its autorelease pool). When the window is closed, The solution would be to get rid of the thread-specific This would add a bit of noise to the implementation, but otherwise should be relatively straightforward. |
GUI toolkits such as wxWidgets and Qt provide their own NSAutoreleasePool objects. To avoid pool corruption, it is required that the pools be nested, which the previous implementation did not guarantee. Furthermore, autorelease pools should always be drained in the same context (function, loop, etc.) that they are created, which was not the case with the previous implementation (https://developer.apple.com/documentation/foundation/nsautoreleasepool). This commit complete removes the AutoreleasePoolWrapper, and functions that use autorelease create and drain their own pools. Should fix crashes in issue SFML#1549 and similar.
GUI toolkits such as wxWidgets and Qt provide their own NSAutoreleasePool objects. To avoid pool corruption, it is required that the pools be nested, which the previous implementation did not guarantee. Furthermore, autorelease pools should always be drained in the same context (function, loop, etc.) that they are created, which was not the case with the previous implementation (https://developer.apple.com/documentation/foundation/nsautoreleasepool). This commit complete removes the AutoreleasePoolWrapper, and functions that use autorelease create and drain their own pools. Should fix crashes in issue SFML#1549 and similar.
GUI toolkits such as wxWidgets and Qt provide their own NSAutoreleasePool objects. To avoid pool corruption, it is required that the pools be nested, which the previous implementation did not guarantee. Furthermore, autorelease pools should always be drained in the same context (function, loop, etc.) that they are created, which was not the case with the previous implementation (https://developer.apple.com/documentation/foundation/nsautoreleasepool). This commit removes long-lived autorelease pools, and instead each function that calls into the Cocoa API creates its own autorelease pool (using the new C++ AutoreleasePool wrapper object). Should fix crashes in issue SFML#1549 and similar.
GUI toolkits such as wxWidgets and Qt provide their own NSAutoreleasePool objects. To avoid pool corruption, it is required that the pools be nested, which the previous implementation did not guarantee. Furthermore, autorelease pools should always be drained in the same context (function, loop, etc.) that they are created, which was not the case with the previous implementation (https://developer.apple.com/documentation/foundation/nsautoreleasepool). This commit removes long-lived autorelease pools, and instead each function that calls into the Cocoa API creates its own autorelease pool (using the new C++ AutoreleasePool wrapper object). Should fix crashes in issue #1549 and similar.
@jecse can you give the master branch a try and see if it actually solved your issue? |
I found the project on my hard disk, so I'm going to give it a shot this weekend. Note, I haven't visited this library in years. |
Did you get around to this? 🙂 |
Thank you for fixing this issue. |
*System specification are as follow...
macOS Mojave -> Mac OS X 10.14.2
wxWidgets 3.1.2 -> --with-osx_cocoa --with-macosx-version-min=10.14 --with-macosx=MacOSX10.14.sdk
SFML 2.5.1 -> macOS OS X 10.7+, compatible with C++11 and libc++
The following code snippet, shown below, comes from a GitHub project that you can find at this link https://gist.github.com/eriknelson/e4ccf32534eb3d25a1ea. Please give Eriknelson credit for his SFML 2.3+ into wxWidgets 3.0 integration demo. This demo is not prefect but it only has one flaw. The application crashes after closing the wxWidgets window.
His example runs as expected but upon closing the wxWidgets windows it crashes with the following error shown below.
I suspect wxControl and sf::RenderWindows are trying the close the NSView, which comes from the GetHandle() call, at the same time.
-James Harris
The text was updated successfully, but these errors were encountered: