Search code examples
c++qtvisual-c++exceptionworker-thread

C++/Qt - Exception in destructor -> abort has been called


Introduction

MSVC 2017 64 bit, Win 10 64 bit, Qt Creator

I have a class CameraControl that builds up a connection to a camera and is a data member of a QMainWindow class:

class RaGaCCMainView : public QMainWindow
{
        Q_OBJECT
    ...

    public:
        explicit RaGaCCMainView(QWidget *parent = nullptr);
        ~RaGaCCMainView();

    private:
        CameraControl cameraControl;
        QThread cameraWorkerThread;
        ...

    ...
};

class CameraControl : public QObject
{
        Q_OBJECT
    ...

    public:
        explicit CameraControl(QObject *parent = nullptr);
        ~CameraControl();
        void stopImageAcquisition();
        ...

    ...
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    RaGaCCMainView w;
    w.setAttribute(Qt::WA_QuitOnClose);
    w.show();

    return a.exec();
}

The CameraControl gets moved to a the cameraWorkerThread:

RaGaCCMainView::RaGaCCMainView(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::RaGaCCMainView)
{
    ...

    this->cameraControl.moveToThread(&(this->cameraWorkerThread));

    // Object should be deletable after the thread finished!
    this->connect(&this->cameraWorkerThread, &QThread::finished, &this->cameraControl, &QObject::deleteLater);

    ... // some connects

    this->cameraWorkerThread.start();
}

The cameraWorkerThread gets quited and terminated in the destructor of RaGaCCMainView:

RaGaCCMainView::~RaGaCCMainView()
{
    this->cameraWorkerThread.quit();
    this->cameraWorkerThread.terminate();
    delete this->ui;
}

As you can see, the main view gets quited if the user closes it (Qt::WA_QuitOnClose). To end the camera connection in a nice way when the user decided to close the main window i call a function stopImageAcquisition which handles some camera stuff (stop acquiring images) and could throw an exception:

CameraControl::~CameraControl()
{
        this->stopImageAcquisition(); // Here an exception could/will be thrown!
        USB1_3M_CloseCamera(this->cameraHandle);
        USB1_3M_TerminateLibrary();
}

The problem

I thought that wouldn't be any problem because thrown things in destructors get ignored anyway.

However when i close the main window w and an exception is thrown i get an abort() has been called message from msvc:

enter image description here

Of course i don't have any clue whats the issue here. I would suggest this issue is related to the treatment of the worker thread...

I would like that the exception get ignored how it's supposed to be (or is this a misunderstanding of the meant behavior too?)

Question

  1. What is causing the issue?
  2. Do i need to use try and catch or is there another viable solution?

I allways appreciate your help.


Solution

  • Your linked answer states that you should catch and drop exceptions from code that you call from your destructor and not re-throw them.

    By default unhandled exceptions in destructors are very much not ignored and will cause issues varying from memory leaks to crashes. Any code that might throw an exception from the destructor should be wrapped in a try/catch and the resulting exception dealt with if possible (e.g. by writing a log message) or just ignored completely.

    Ideally you should structure your code so that you don't call exception generating code from destructors.