Tom94 / tev

High dynamic range (HDR) image viewer for graphics people
BSD 3-Clause "New" or "Revised" License
1.03k stars 87 forks source link

[osx] Crash when quitting tev #128

Closed mmp closed 3 years ago

mmp commented 3 years ago

I just noticed this... (Possibly related to the #126 fix?) To reproduce, run tev x.png with the attached, hit command-q to quit, and it crashes.

x

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1e0)
  * frame #0: 0x00007fff5ac82137 libsystem_pthread.dylib`pthread_mutex_lock
    frame #1: 0x00007fff57cbd959 libc++.1.dylib`std::__1::mutex::lock() + 9
    frame #2: 0x00000001001ce433 tev`std::__1::lock_guard<std::__1::mutex>::lock_guard(this=0x00007ffeefbfce30, __m=0x00000000000001e0) at __mutex_base:104:27
    frame #3: 0x00000001001ce3ad tev`std::__1::lock_guard<std::__1::mutex>::lock_guard(this=0x00007ffeefbfce30, __m=0x00000000000001e0) at __mutex_base:104:21
    frame #4: 0x00000001001cdbde tev`tev::SharedQueue<std::__1::function<void ()> >::push(this=0x00000000000001b0, newElem= Function = _mh_execute_header )>) at SharedQueue.h:28:37
    frame #5: 0x000000010021ea4a tev`void tev::ImageViewer::scheduleToUiThread<std::__1::function<void ()> >(this=0x0000000000000000, fun= Function = _mh_execute_header )> const&) at ImageViewer.h:136:20
    frame #6: 0x000000010021e9d7 tev`tev::scheduleToMainThread(fun= Function = _mh_execute_header )> const&) at main.cpp:37:19
    frame #7: 0x00000001000ddb24 tev`tev::GlTexture::~GlTexture(this=0x000000010235bd58) at GlTexture.h:37:13
    frame #8: 0x00000001000d2f05 tev`tev::GlTexture::~GlTexture(this=0x000000010235bd58) at GlTexture.h:32:27
    frame #9: 0x0000000100217ee2 tev`tev::UberShader::~UberShader(this=0x000000010235bcf0) at UberShader.cpp:206:1
    frame #10: 0x0000000100217f45 tev`tev::UberShader::~UberShader(this=0x000000010235bcf0) at UberShader.cpp:204:27
    frame #11: 0x000000010011fe77 tev`tev::ImageCanvas::~ImageCanvas(this=0x000000010235bbc0) at ImageCanvas.h:24:7
    frame #12: 0x0000000100117b65 tev`tev::ImageCanvas::~ImageCanvas(this=0x000000010235bbc0) at ImageCanvas.h:24:7
    frame #13: 0x0000000100117b89 tev`tev::ImageCanvas::~ImageCanvas(this=0x000000010235bbc0) at ImageCanvas.h:24:7
    frame #14: 0x00000001003d5dac tev`nanogui::Object::decRef(this=0x000000010235bbc0, dealloc=true) const at common.cpp:345:9
    frame #15: 0x00000001003dbdb0 tev`nanogui::Widget::~Widget(this=0x000000010235b810) at widget.cpp:35:20
    frame #16: 0x00000001003dbf15 tev`nanogui::Widget::~Widget(this=0x000000010235b810) at widget.cpp:32:19
    frame #17: 0x00000001003dbf39 tev`nanogui::Widget::~Widget(this=0x000000010235b810) at widget.cpp:32:19
    frame #18: 0x00000001003d5dac tev`nanogui::Object::decRef(this=0x000000010235b810, dealloc=true) const at common.cpp:345:9
    frame #19: 0x00000001003dbdb0 tev`nanogui::Widget::~Widget(this=0x000000010235b770) at widget.cpp:35:20
    frame #20: 0x00000001003dbf15 tev`nanogui::Widget::~Widget(this=0x000000010235b770) at widget.cpp:32:19
    frame #21: 0x00000001003dbf39 tev`nanogui::Widget::~Widget(this=0x000000010235b770) at widget.cpp:32:19
    frame #22: 0x00000001003d5dac tev`nanogui::Object::decRef(this=0x000000010235b770, dealloc=true) const at common.cpp:345:9
    frame #23: 0x00000001003dbdb0 tev`nanogui::Widget::~Widget(this=0x0000000102225460) at widget.cpp:35:20
    frame #24: 0x00000001003f211b tev`nanogui::Screen::~Screen(this=0x0000000102225460) at screen.cpp:389:1
    frame #25: 0x000000010018e8b1 tev`tev::ImageViewer::~ImageViewer(this=0x0000000102225460) at ImageViewer.cpp:447:1
    frame #26: 0x000000010018e915 tev`tev::ImageViewer::~ImageViewer(this=0x0000000102225460) at ImageViewer.cpp:442:29
    frame #27: 0x000000010018e939 tev`tev::ImageViewer::~ImageViewer(this=0x0000000102225460) at ImageViewer.cpp:442:29
    frame #28: 0x0000000100268abf tev`std::__1::default_delete<tev::ImageViewer>::operator(this=0x00000001007e39c0, __ptr=0x0000000102225460)(tev::ImageViewer*) const at memory:2335:5
    frame #29: 0x0000000100223a3f tev`std::__1::unique_ptr<tev::ImageViewer, std::__1::default_delete<tev::ImageViewer> >::reset(this=0x00000001007e39c0, __p=0x0000000000000000) at memory:2648:7
    frame #30: 0x0000000100222acc tev`tev::mainFunc(arguments=size=2) at main.cpp:405:18
    frame #31: 0x0000000100223d16 tev`main(argc=2, argv=0x00007ffeefbff6d0) at main.cpp:433:9
    frame #32: 0x00007fff5aa903d5 libdyld.dylib`start + 1
Tom94 commented 3 years ago

Indeed it is! While I can't reproduce the crash on my end, there is definitely something dodgy going on with the order of desctruction. (Use-after-free to be precise.)

Thanks for reporting.

I guess that's what I get for hacking my way around RAII. And my best idea for a fix is to hack around it even more. I really should check out some existing OGL libraries and see how they do it.