Search code examples
c++multithreadingc++11wxwidgets

wxWidgets - terminate called without an active exception (using std::thread)


I am writing GUI application which use my own library which is based on boost::asio an C++11 standard library. This is implementation of gui_client::OnInit and gui_client::OnExit methods of class gui_client which derives from wxApp:

bool gui_client::OnInit()
{
    io_service_ = new boost::asio::io_service;
    client_ = new client(*io_service_);
    frame = new main_frame();

    std::thread reader([this]() {
        // thread code
    });

    reader_thread = &reader;

    frame->Show();
    Debug("Returning OnInit");
    return true;
}

int gui_client::OnExit()
{
    reader_thread->join();
    return 0;
}

Everything compiles and application starts. I see debug information in command line ('Returning OnInit') and then:

terminate called without an active exception

I tried to set breakpoints in gdb on some wxApp functions, but I cannot find the place where error is returned. gui_client class has only three methods:

  • virtual bool OnInit()
  • virtual int OnExit()
  • client * get_client()

When I do not start reader thread (std::thread reader) everything works well. When I started thread with empty loop in lambda function I got error which I mentioned above. I'm also sure that thread code is correct because the same code works well in CLI testing application.

I use wxWidgets 3.0.1.0 and g++ 4.7.2 (Debian). I use this g++ command for comilation:

g++ `wx-config --version=3.0 --cxxflags` -std=c++11 -I./headers -I../headers -L../lib/Debug -DDEBUG -g -c -o [obj_file] [source]

and this command for linking:

g++ `wx-config --version=3.0 --cxxflags` -std=c++11 -I./headers -I../headers -L../lib/Debug -DDEBUG -g [obj_files] -ltamandua `wx-config --version=3.0 --libs` -lboost_system -pthread -o [output]

Solution

  • Problem is here:

    std::thread reader([this]() {
        // thread code
    });
    
    reader_thread = &reader;
    

    reader will be destroyed after OnInit function ends (and terminate will be called, since thread is joinable). You should use smart-pointer in class in this case, or create reader_thread using new, or simply save thread in object and assign it to your reader_thread (reader_thread should be object, not pointer) via move.

    1) reader_thread = std::make_shared<std::thread>([this]() {});

    2) reader_thread = new std::thread([this]() {});

    3)

    std::thread reader([this](){});
    reader_thread = std::move(reader);