Skip to content
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

Closed
jecse opened this issue Jan 23, 2019 · 13 comments · Fixed by #1820
Closed

Crash after closing wxWidgets with SFML-window #1549

jecse opened this issue Jan 23, 2019 · 13 comments · Fixed by #1820

Comments

@jecse
Copy link

jecse commented Jan 23, 2019

*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.

#include <iostream>
#include <wx/wx.h>
#include <memory>
#include <SFML/Graphics.hpp>

#ifdef __WXGTK__
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#endif

using namespace std;

static const int kDefaultWindowWidth = 1280;
static const int kDefaultWindowHeight = 720;
static const int kCanvasMargin = 0;

struct wxSfmlCanvas : public wxControl, public sf::RenderWindow
{
  wxSfmlCanvas(
    wxWindow *parent = nullptr,
    wxWindowID windowId = -1,
    const wxPoint &position = wxDefaultPosition,
    const wxSize &size = wxDefaultSize,
    long style = 0) :
  wxControl(parent, windowId, position, size, style)
  {
    createRenderWindow();
  }

  virtual void onUpdate(){};

  void onIdle(wxIdleEvent& event)
  {
    // Send a paint message when control is idle, to ensure max framerate
    Refresh();
  }

  void onPaint(wxPaintEvent& event)
  {
    wxPaintDC dc(this);     // Prepare control to be repainted
    onUpdate();             // Tick update
    display();              // Draw
  }

  // Explicitly overriding prevents wxWidgets from drawing, which could result in flicker
  void onEraseBackground(wxEraseEvent& event){}

  void createRenderWindow()
  {
#ifdef __WXGTK__
    // gtk_widget_realize(m_wxwindow);
    // gtk_widget_set_double_buffered(m_wxwindow, false);

    // GdkWindow *gdkWindow = gtk_widget_get_window((GtkWidget*)GetHandle());
    // XFlush(GDK_WINDOW_XDISPLAY(gdkWindow));

    // sf::RenderWindow::create(GDK_WINDOW_XWINDOW(gdkWindow));
#else
    sf::RenderWindow::create(GetHandle());
#endif
  }

  void setwxWindowSize(const wxSize& size)
  {
    this->SetSize(size);
  }

  void setRenderWindowSize(const sf::Vector2u& size)
  {
    this->setSize(size);
  }

  virtual ~wxSfmlCanvas(){};

wxDECLARE_EVENT_TABLE();
};

struct Canvas : public wxSfmlCanvas
{
  Canvas(
    wxWindow* parent,
    wxWindowID id,
    wxPoint position,
    wxSize size,
    long style = 0) :
  wxSfmlCanvas(parent, id, position, size, style)
  {
  }

  virtual void onUpdate()
  {
    clear(sf::Color::Yellow);
    sf::CircleShape shape(50);
    shape.setFillColor(sf::Color(150, 50, 250));
    shape.setOutlineThickness(10);
    shape.setOutlineColor(sf::Color(250, 150, 100));
    sf::RectangleShape line(sf::Vector2f(150, 5));
    line.rotate(45);
    this->draw(shape);
    this->draw(line);
  }

  void onResize(wxSizeEvent& event)
  {
    auto size = event.GetSize();
    auto newCanvasWidth = size.x - (2 * kCanvasMargin);
    auto newCanvasHeight = size.y - (2 * kCanvasMargin);
    sf::Vector2u v(newCanvasWidth,newCanvasHeight);
    wxSize s(newCanvasWidth,newCanvasHeight);
    this->SetSize(s); //wx setSize
    this->setSize(v); //SFML setSize
  }
};

struct AppFrame : public wxFrame
{
  AppFrame(const wxString& title, const wxPoint& pos, const wxSize& size) :
    wxFrame(NULL, wxID_ANY, title, pos, size),
    _panel(new wxPanel(this)),
    _canvas(new Canvas(
      _panel.get(),
      wxID_ANY,
      wxPoint(kCanvasMargin, kCanvasMargin),
      wxSize(kDefaultWindowWidth - (2 * kCanvasMargin), kDefaultWindowHeight - (2 * kCanvasMargin))
    ))
  {
    _panel->SetBackgroundColour(*wxCYAN);

    ////////////////////////////////////////////////////////////////////////////////
    // Probably due to some RTTI, IDE is getting confused by this dynamic call
    // and doesn't understand the correct Bind overload. Causes non sequitur errors
    // to display in the inspector. Suppress.
    //
    // Dynamic binding is cleanest here, since we don't want to hook up our resize
    // handler until our dependencies (Canvas namely) have finished their initialization
    ////////////////////////////////////////////////////////////////////////////////
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wint-conversion"
    Bind(wxEVT_SIZE, &AppFrame::onResize, this);
    #pragma clang diagnostic pop
    ////////////////////////////////////////////////////////////////////////////////

  }

  void onResize(wxSizeEvent& event)
  {
    _canvas->onResize(event);
    event.Skip();
  }

  unique_ptr<wxPanel> _panel;
  unique_ptr<Canvas> _canvas;
};

struct App : public wxApp
{
  virtual bool OnInit()
  {
    auto frame = new AppFrame("SFML Canvas Demo", wxPoint(100, 100),
                              wxSize(kDefaultWindowWidth, kDefaultWindowHeight));
    frame->Show(true);
    return true;
  }
};

wxBEGIN_EVENT_TABLE(wxSfmlCanvas, wxControl)
  EVT_IDLE(wxSfmlCanvas::onIdle)
  EVT_PAINT(wxSfmlCanvas::onPaint)
  EVT_ERASE_BACKGROUND(wxSfmlCanvas::onEraseBackground)
wxEND_EVENT_TABLE()

wxIMPLEMENT_APP(App);

His example runs as expected but upon closing the wxWidgets windows it crashes with the following error shown below.

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Reason:    Namespace OBJC, Code 0x1

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib        	0x00007fff64e7c01e __abort_with_payload + 10
1   libsystem_kernel.dylib        	0x00007fff64e77541 abort_with_payload_wrapper_internal + 82
2   libsystem_kernel.dylib        	0x00007fff64e774ef abort_with_reason + 22
3   libobjc.A.dylib               	0x00007fff63c58674 _objc_fatalv(unsigned long long, unsigned long long, char const*, __va_list_tag*) + 108
4   libobjc.A.dylib               	0x00007fff63c58526 _objc_fatal(char const*, ...) + 135
5   libobjc.A.dylib               	0x00007fff63c62525 (anonymous namespace)::AutoreleasePoolPage::fastcheck(bool) + 125
6   libobjc.A.dylib               	0x00007fff63c4a9f7 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 65
7   com.apple.CoreFoundation      	0x00007fff37ab9ee6 _CFAutoreleasePoolPop + 22
8   com.apple.Foundation          	0x00007fff39e66a5e -[NSAutoreleasePool drain] + 144
9   org.sfml-dev.sfml-window      	0x000000010ffc86a5 drainThreadPool() + 37
10  org.sfml-dev.sfml-window      	0x000000010ffc76e4 sf::priv::WindowImplCocoa::~WindowImplCocoa() + 148
11  org.sfml-dev.sfml-window      	0x000000010ffc772f sf::priv::WindowImplCocoa::~WindowImplCocoa() + 15
12  org.sfml-dev.sfml-window      	0x000000010ffb85ca sf::Window::~Window() + 58
13  org.wxwindows.                	0x000000010fe8dc75 wxSfmlCanvas::~wxSfmlCanvas() + 37 (main.cpp:73)
14  org.wxwindows.                	0x000000010fe8dc45 Canvas::~Canvas() + 21 (main.cpp:78)
15  org.wxwindows.                	0x000000010fe8d505 Canvas::~Canvas() + 21 (main.cpp:78)
16  org.wxwindows.                	0x000000010fe8d529 Canvas::~Canvas() + 25 (main.cpp:78)
17  org.wxwindows.                	0x000000010fe8e740 AppFrame::~AppFrame() + 304 (memory:2285)
18  org.wxwindows.                	0x000000010fe8b335 AppFrame::~AppFrame() + 21 (main.cpp:125)
19  org.wxwindows.                	0x000000010fe8b359 AppFrame::~AppFrame() + 25 (main.cpp:125)
20  libwx_osx_cocoau-3.1.2.0.0.dylib	0x000000010fffdd3d wxAppConsoleBase::ProcessIdle() + 157
21  libwx_osx_cocoau-3.1.2.0.0.dylib	0x0000000110238476 wxAppBase::ProcessIdle() + 22
22  libwx_osx_cocoau-3.1.2.0.0.dylib	0x000000011018550a wxApp::ProcessIdle() + 26
23  libwx_osx_cocoau-3.1.2.0.0.dylib	0x00000001100e41fc wxCFEventLoop::OSXCommonModeObserverCallBack(__CFRunLoopObserver*, int, void*) + 92
24  com.apple.CoreFoundation      	0x00007fff37b459cd __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
25  com.apple.CoreFoundation      	0x00007fff37b45902 __CFRunLoopDoObservers + 452
26  com.apple.CoreFoundation      	0x00007fff37ae7558 __CFRunLoopRun + 1469
27  com.apple.CoreFoundation      	0x00007fff37ae6d48 CFRunLoopRunSpecific + 463
28  com.apple.HIToolbox           	0x00007fff36d7dab5 RunCurrentEventLoopInMode + 293
29  com.apple.HIToolbox           	0x00007fff36d7d7eb ReceiveNextEventCommon + 618
30  com.apple.HIToolbox           	0x00007fff36d7d568 _BlockUntilNextEventMatchingListInModeWithFilter + 64
31  com.apple.AppKit              	0x00007fff35038363 _DPSNextEvent + 997
32  com.apple.AppKit              	0x00007fff35037102 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
33  com.apple.AppKit              	0x00007fff35031165 -[NSApplication run] + 699
34  libwx_osx_cocoau-3.1.2.0.0.dylib	0x00000001101f0dff wxGUIEventLoop::OSXDoRun() + 207
35  libwx_osx_cocoau-3.1.2.0.0.dylib	0x00000001100e4ab1 wxCFEventLoop::DoRun() + 49
36  libwx_osx_cocoau-3.1.2.0.0.dylib	0x000000011002fcae wxEventLoopBase::Run() + 158
37  libwx_osx_cocoau-3.1.2.0.0.dylib	0x000000010fffda13 wxAppConsoleBase::MainLoop() + 99
38  libwx_osx_cocoau-3.1.2.0.0.dylib	0x000000011018555a wxApp::OnRun() + 26
39  libwx_osx_cocoau-3.1.2.0.0.dylib	0x0000000110067763 wxEntry(int&, wchar_t**) + 131
40  org.wxwindows.                	0x000000010fe883b6 main + 38 (main.cpp:182)
41  libdyld.dylib                 	0x00007fff64d24ed9 start + 1

Thread 1:
0   libsystem_pthread.dylib       	0x00007fff64f173f8 start_wqthread + 0
1   ???                           	0x0000000054485244 0 + 1414025796

Thread 2:: Dispatch queue: NSCGSDisableUpdates
0   libsystem_kernel.dylib        	0x00007fff64e5e17a mach_msg_trap + 10
1   libsystem_kernel.dylib        	0x00007fff64e5e6d0 mach_msg + 60
2   com.apple.SkyLight            	0x00007fff5dc44bc5 CGSUpdateManager::enable_updates_common() + 577
3   com.apple.SkyLight            	0x00007fff5dbe7e3b CGSUpdateManager::enable_update(unsigned long long) + 317
4   libdispatch.dylib             	0x00007fff64cd5d53 _dispatch_call_block_and_release + 12
5   libdispatch.dylib             	0x00007fff64cd6dcf _dispatch_client_callout + 8
6   libdispatch.dylib             	0x00007fff64cdd124 _dispatch_lane_serial_drain + 618
7   libdispatch.dylib             	0x00007fff64cddbdc _dispatch_lane_invoke + 388
8   libdispatch.dylib             	0x00007fff64ce6090 _dispatch_workloop_worker_thread + 603
9   libsystem_pthread.dylib       	0x00007fff64f1760b _pthread_wqthread + 409
10  libsystem_pthread.dylib       	0x00007fff64f17405 start_wqthread + 13

Thread 3:
0   libsystem_pthread.dylib       	0x00007fff64f173f8 start_wqthread + 0
1   ???                           	0x0000000054485244 0 + 1414025796

Thread 4:: com.apple.NSEventThread
0   libsystem_kernel.dylib        	0x00007fff64e5e17a mach_msg_trap + 10
1   libsystem_kernel.dylib        	0x00007fff64e5e6d0 mach_msg + 60
2   com.apple.CoreFoundation      	0x00007fff37ae80c2 __CFRunLoopServiceMachPort + 337
3   com.apple.CoreFoundation      	0x00007fff37ae7611 __CFRunLoopRun + 1654
4   com.apple.CoreFoundation      	0x00007fff37ae6d48 CFRunLoopRunSpecific + 463
5   com.apple.AppKit              	0x00007fff35040f89 _NSEventThread + 160
6   libsystem_pthread.dylib       	0x00007fff64f18305 _pthread_body + 126
7   libsystem_pthread.dylib       	0x00007fff64f1b26f _pthread_start + 70
8   libsystem_pthread.dylib       	0x00007fff64f17415 thread_start + 13

Thread 5:
0   libsystem_pthread.dylib       	0x00007fff64f173f8 start_wqthread + 0

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000002000209  rbx: 0x0000000000000080  rcx: 0x00007ffedfd767c8  rdx: 0x0000000000000000
  rdi: 0x0000000000000008  rsi: 0x0000000000000001  rbp: 0x00007ffedfd76810  rsp: 0x00007ffedfd767c8
   r8: 0x00007febce519d50   r9: 0x0000000000000080  r10: 0x0000000000000000  r11: 0x0000000000000246
  r12: 0x0000000000000000  r13: 0x0000000000000000  r14: 0x0000000000000001  r15: 0x0000000000000008
  rip: 0x00007fff64e7c01e  rfl: 0x0000000000000246  cr2: 0x0000000116681000
  
Logical CPU:     0
Error Code:      0x02000209
Trap Number:     133

I suspect wxControl and sf::RenderWindows are trying the close the NSView, which comes from the GetHandle() call, at the same time.

-James Harris

@eXpl0it3r
Copy link
Member

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...

@mantognini
Copy link
Member

I quickly looked into it.

objc[32687]: autorelease pool page 0x10189b000 corrupted
  magic     0x02610f00 0x00006000 0xa2904f60 0x00007fff
  should be 0xa1a1a1a1 0x4f545541 0x454c4552 0x21455341
  pthread   0x0
  should be 0x1000d35c0

Is wx corrupting pthread state?

The crash happens in AutoreleasePoolWrapper.mm's destroyPool() function. But I have no idea what's happening. I tried removing all the pthread related stuff from this file but this hasn't solve the issue (I was expecting to see the bug go away without introducing another one because all allocations are done in the main thread with this test). Instead, I got different values:

objc[36432]: autorelease pool page 0x102071000 corrupted
  magic     0x9846a19d 0x00000000 0xfecc1b72 0x4447417b
  should be 0xa1a1a1a1 0x4f545541 0x454c4552 0x21455341
  pthread   0x10f8a72c272bc602
  should be 0x1000d35c0

Maybe someone more familiar with wx could help?

@jecse
Copy link
Author

jecse commented Feb 16, 2019

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

@jecse
Copy link
Author

jecse commented Feb 19, 2019

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.

@"Cannot close SFML area when SFML is integrated in a NSView.\r\n"
@"Cannot close SFML area when SFML is integrated in a NSView.\r\n"
@"objc[6991]: autorelease pool page 0x1018b2000 corrupted\r\n"
@"  magic     0x81b800c0 0x00007fff 0x018dfcd8 0x00000001\r\n"
@"  should be 0xa1a1a1a1 0x4f545541 0x454c4552 0x21455341\r\n"
@"  pthread   0x7fff21f7e158\r\n"
@"  should be 0x1001025c0\r\n"
@"\r\n"

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

@jecse
Copy link
Author

jecse commented Feb 23, 2019

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.

@eXpl0it3r
Copy link
Member

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?

@jecse
Copy link
Author

jecse commented Feb 26, 2019

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.

@eXpl0it3r
Copy link
Member

Same issue reported for Qt + SFML on the forum.

@jqdg would you by any chance have an idea for a fix here, given that you knew quite some stuff in a similar area?

jqdg added a commit to jqdg/SFML that referenced this issue Aug 24, 2021
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.
@jqdg
Copy link
Contributor

jqdg commented Aug 25, 2021

Same issue reported for Qt + SFML on the forum.

@jqdg would you by any chance have an idea for a fix here, given that you knew quite some stuff in a similar area?

The issue here is that SFML's handling of NSAutoreleasePool is not really correct according to Apple's documentation. In particular:

You should always drain an autorelease pool in the same context (invocation of a method or function, or body of a loop) that it was created.

What SFML does is it creates a NSAutoreleasePool when a Cocoa window is created (for example in the constructor of WindowImplCocoa). When events are polled, the pool is drained, and a new one is created. Finally, when the window is destroyed, the autorelease pool is drained and released. The created autorelease pools live longer than the context (function) in which they are created.

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, ~WindowImplCocoa is called, and SFML's outer autorelease pool is drained before wxWidget's inner autorelease pool is.


The solution would be to get rid of the thread-specific NSAutoreleasePool that SFML currently creates. However, an autorelease pool is required whenever calls are made to the Cocoa API (otherwise you could leak memory). So, every function that calls into Cocoa APIs would need to have an autorelease pool created (either manually, using NSAutoreleasePool, using the @autoreleasepool directive, or with a RAII-style C++ wrapper that drains the pool in the destructor).

This would add a bit of noise to the implementation, but otherwise should be relatively straightforward.

jqdg added a commit to jqdg/SFML that referenced this issue Aug 29, 2021
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.
jqdg added a commit to jqdg/SFML that referenced this issue Aug 29, 2021
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.
jqdg added a commit to jqdg/SFML that referenced this issue Aug 29, 2021
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.
eXpl0it3r pushed a commit that referenced this issue Sep 15, 2021
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.
@eXpl0it3r
Copy link
Member

@jecse can you give the master branch a try and see if it actually solved your issue?

@jecse
Copy link
Author

jecse commented Sep 16, 2021

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.

@eXpl0it3r eXpl0it3r added this to Discussion in SFML 2.6.0 via automation Oct 18, 2021
@eXpl0it3r eXpl0it3r added this to the 2.6 milestone Oct 18, 2021
@eXpl0it3r eXpl0it3r moved this from Discussion to Done in SFML 2.6.0 Oct 18, 2021
@eXpl0it3r
Copy link
Member

Did you get around to this? 🙂

@jecse
Copy link
Author

jecse commented Oct 18, 2021

Thank you for fixing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
SFML 2.6.0
  
Done
Development

Successfully merging a pull request may close this issue.

4 participants