Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::thread program crashes on throwing std::exception

I am puzzled as to why this program crashes. This is the entire program

#include<fstream>
#include<string>
#include<iostream>
#include <exception>
#include <boost/thread/thread.hpp>

    void func( const std::string& filename )
    {
        std::ofstream outFile( filename.c_str(), std::ios::binary);
        if( !outFile.is_open() )
        {
            std::string err("Could not open file ");
            err.append(filename);
            err.append(" for writing");
            throw std::exception(err.c_str());
        }
    }

    int main()
    {
        std::string filename("xX:\\does_not_exist.txt");
        try
        {
            boost::thread thrd(boost::bind(&func, filename ));
            thrd.join();
        //  func( filename ); // calling this does not cause a crash
        }
        catch( const std::exception& ex)
        {
            std::cout << ex.what() << std::endl;
        }
        return 0;
    }

Environment
Windows 7
Visual Studio Express 2008
boost: tried both 1.44.0 and 1.46.1
Linking ( tried both dynamic and static )

like image 938
user754425 Avatar asked May 22 '11 10:05

user754425


3 Answers

The basic problem is that in the current standard there is no support for moving exceptions from one thread to another. When the exception is left uncaught in the newly created thread, it reaches the top of the stack and finalizes the program as if an exception had been left uncaught in main. Consider that the try in main is in the stack of the main thread, but the exception is in a completely different stack.

That is documented in boost thread: http://www.boost.org/doc/libs/1_46_1/doc/html/thread/thread_management.html#thread.thread_management.thread

In the upcoming standard there is support for moving exceptions from one thread to another, but you would have to either catch and move manually or use a higher level constructs like std::future.

like image 112
David Rodríguez - dribeas Avatar answered Nov 18 '22 05:11

David Rodríguez - dribeas


You are throwing an exception in the thread and there is no surrounding catch block to catch the exception. The handler is around the place where you create the thread but the thread is running in it own separate context.

If you want to catch an exception thrown in the thread then you need to do so inside that thread.

like image 2
jcoder Avatar answered Nov 18 '22 06:11

jcoder


Boost.Exception has a way of transporting of exceptions between threads described in http://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_exception_ptr.html

This is also part of the upcoming C++0X standard.

like image 1
dalle Avatar answered Nov 18 '22 04:11

dalle