c++11 thread: sub-thread throws exception leads to main thread crash - c++

I was expecting that the status of sub-thread, whether they succeed or not, should not crash main thread.
So I had a quick test:
#include <thread>
#include <iostream>
#include <exception>
using namespace std;
using namespace std::chrono;
void th_function() {
this_thread::sleep_for(chrono::seconds(2));
throw 1; // the criminal here!
}
int main() {
auto th = thread{ th_function };
this_thread::sleep_for(chrono::seconds(1));
cout << "1" << endl;
th.join();
cout << "2" << endl;
return 0;
}
The running result is:
1
Program stderr
terminate called after throwing an instance of 'int'
Well, seems the throw 1 call leads to main thread crash. I think for c++, each thread has its own runtime stack and exception-process chain.
Then why in my case, sub-thread exception will terminate main thread?
Thanks.

It is true that exceptions handling is localized to a single thread, but as always, not catching an exception at all causes a call to std::terminate, which in turn terminates the whole program. The same applies to other conditions resulting in a call to std::terminate, e.g. throwing from a destructor during stack unwinding or letting an exception escape a noexcept function. These are all considered unrecoverable errors.
You can use e.g. std::async if you need to continue execution after an unhandled exception in the thread. std::async includes functionality to catch otherwise uncaught exceptions and stores/forwards them in a std::future, so that the main thread can receive them.

Related

My code is exiting with use-after-free error but I don't know why?

I'm a multithreading beginner and I'm wring the below code:
#include <iostream>
#include <functional>
#include <thread>
#include <mutex>
#include <future>
#include <unistd.h>
using namespace std;
class Foo {
public:
Foo() {}
~Foo() { cout << "foo dtor" << endl; }
void first(function<void()> printFirst) {
printFirst();
}
void second(function<void()> printSecond) {
printSecond();
}
void third(function<void()> printThird) {
printThird();
}
};
int main() {
Foo foo;
thread t1([&foo] {
function<void()> print11 = [] { cout << "1" << endl; };
foo.first(print11);
});
thread t2([&foo] {
function<void()> print21 = [] { cout << "2" << endl; };
foo.second(print21);
});
thread t3([&foo] {
function<void()> print31 = [] { cout << "3" << endl; };
foo.third(print31);
});
sleep(2);
// t1.join();
// t2.join();
// t3.join();
return 0;
}
And I'm getting the error
"Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
If I uncomment the three join() lines, the program exit normally.
I have a feeling that the error is due to use after free, but cannot explain why. What I'm thinking is the main thread will sleep 2 seconds before it really finishes, and during the main thread is sleeping, the t1, t2, t3 should already finish. Hence, even if foo is destroyed, the three thread won't use it after 2 seconds. As far as I understand, it should not have use after free problem. Could anybody explain? Thanks!
This does not look to me like a use after free problem, and it's not a race condition either. It's required behavior. Attempting to destroy a thread object that is in a joinable state (which yours would be under the circumstances) is required to terminate the program (N4835, §[thread.thread.destr]/1):
~thread();
If joinable(), calls terminate(). Otherwise, has no effects. [Note: Either implicitly detaching or
joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach)
or performance (for join) bugs encountered only when an exception is thrown. Thus the programmer
must ensure that the destructor is never executed while the thread is still joinable. —end note]
A thread is joinable() from the time it starts to run until the time it is join()ed or detach()ed.
Summary
Destroying a thread must abort the program if the thread is in a joinable state. To avoid this, join() the thread(s) before destroying them.
The operating system is under no obligation to run your other threads when you sleep(2). It could let Google Chrome have that time slice, or it could use it to do its own background tasks, or it could just sit there on its thumbs.
That logic you just went through of "This thread should only last two seconds at most, so sleeping will do it" is called a race condition. You've got two threads and you're making big assumptions about what order things in those threads will happen, without actually enforcing those assumptions. Effectively, your threads enter into a race: if the three child threads win the race, then your program works fine, but if the main thread wins the race, then your program exhibits undefined behavior. And if your program has a chance of exhibiting undefined behavior, then that means that your program's behavior is undefined.
By adding the join calls, you enforce your assumption. You demand that the main thread cannot exit until the other three threads finish, which is what you were implicitly assuming before. This makes your program's behavior defined.

can't catch exception in main thread when other thread active and has try-catch

Main thread can't catch an exception (that was thrown in the main thread) while another thread with try-catch is still active. How to solve it?
example:
int main()
{
// try-catch of main thread
try
{
// run a thread
std::thread cThread([]()
{
// try-catch of secondary thread
try
{
// makes thread works for 500 ms in order main thread will call
// throw while thread is still active.
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
catch (...)
{
}
});
// Any call to throw BEFORE thread is finished, won't be catch.
// HOW TO SOLVE IT??
throw 1;
// wait thread finished
cThread.join();
// IF YOU PUT THE "throw 1" HERE (AFTER THREAD FINISHED), IT WILL BE
// CATCH.
}
catch (int e)
{
std::cout << "Catched exception " << e << " in main";
}
return 0;
}
It's not so much that the exception isn't caught as it is that destroying a joinable thread terminates the process.
So your program terminates before the exception handler can be executed.
If you declare the thread outside the try-catch block, the exception will be caught.
Remember that you also need to join the thread if the exception was thrown.
You've got something wrong. I mean, you've misunderstood something.
It can't be about try-catch. 'throw' and 'try-catch' are intra-thread things, they live only on the current thread, whatever it would be at the moment of throwing, main thread or the other.
Another thread cannot catch exception thrown from current thread. Exceptions does not cross threads, unless you really want it and implement it as, for example, something on current thread catches the exception and passed them to other thread and then re-throws/etc these exceptions there. You don't have any such things, so it cannot be it.
You have a join() call after the throw, and you expect that throw 1 will skip over it. That's true. However, there's also the std::thread cThread variable in the scope.
Since the thread is running, and due to throw 1 the thread has never been join()ed yet, then the expected thing to see would be program termination (see https://stackoverflow.com/a/13984169/717732), because the destructor of std::thread would detect the un-join()ed thread. That means, the std::cout << "Catched exception " << e << " in main"; should never be called. Even if the thread has somehow finished, your program should still terminate, since it does not change the fact it was not join()ed (see https://en.cppreference.com/w/cpp/thread/thread/joinable)
However, depending on library, compiler, debugger, etc, the effect you see may differ. For example, if you run it in a debugger, it may wait until all threads finish, and you'd get the effect of "waiting until inner thread finished". Hard to say.
If you actually see the "Catched exception " << e << " line running, the you've got a real problem. Either you are running something else than your current code, or your stdlib is broken. A broken stdlib might for example do a silent join() in the destructor of std::thread instead of terminating the program. Who knows. Broken lib can do many things.
Thanks to molbdnilo and quetzalcoatl.
I now made the code works by using std::async instead of std::thread:
First, the problem is not related to try-catch in the thread. It was mine mistake to think it is. So here is a failure code:
int main()
{
// try-catch of main thread
try
{
// run a thread
std::thread cThread([]()
{
});
// Any call to throw BEFORE thread join won't be catch.
// HOW TO SOLVE IT??
throw 1;
// wait thread finished
cThread.join();
// IF YOU PUT THE "throw 1" HERE (AFTER THREAD FINISHED), IT WILL BE
// CATCH.
}
catch (int e)
{
std::cout << "Catched exception " << e << " in main";
}
return 0;
}
And a code that works:
int main()
{
std::future<void> cF;
// try-catch of main thread
try
{
// run a thread
cF = std::async(std::launch::async, []()
{
});
// You can call throw , it will be catch :)
throw 1;
// wait thread finished
if (cF.valid())
{
cF.get();
}
}
catch (int e)
{
std::cout << "Catched exception " << e << " in main";
}
return 0;
}

is it possible to set a promise in a signal handler?

I was looking for a way to stop a thread that perform a task every 2 seconds. I decided to try to use a std::promise/future so that the thread can exit immediately when the promise is set.
#include <future>
#include <iostream>
#include <chrono>
#include <csignal>
std::promise<void> stop;
int main() {
std::signal(SIGINT, [] (int) { stop.set_value(); } );
auto future = stop.get_future();
while (future.wait_for(std::chrono::seconds(1)) != std::future_status::ready) {
std::cout << "I'm still there" << std::endl;
}
}
Actually this does not work and crashes that way:
$ ./a.out I'm still there
^Cterminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1 Abandon
(core dumped)
Ok, One should take care of what he does in handler context, but I must say I was not expecting this crash; and I don't really understand it...
Do you have any idea?
I believe what you have here is undefined behaviour as a result of calling a standard library function (not in list of signal safe functions) in the signal handler.
The limitations on the signal handler function (that is user-defined) are extensive and are documented here.
Another thing to watch out for is if the signal handler refers to any object with static or thread-local(since C++11) storage duration that is not std::atomic(since C++11) or volatile std::sig_atomic_t.
And as #BasileStarynkevitch pointed out, if you are on Linux, ensure that only async-signal-safe functions are called from the signal handler.

Proper way to terminate a thread in c++

I'm learning about multithreading and I wrote this code:
#include <iostream>
#include <mutex>
#include <thread>
#include <string>
#include <chrono>
#include <condition_variable>
int distance = 20;
int distanceCovered = 0;
std::condition_variable cv;
std::mutex mu;
void keep_moving(){
while(true){
std::cout << "Distance is: " << distanceCovered << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
distanceCovered++;
if(distanceCovered == distance){
cv.notify_one();
std::terminate();
}
}
}
void wake_me_up()
{
std::unique_lock<std::mutex> ul(mu);
cv.wait( ul, []{ return distanceCovered==distance; }); // protects the lines of code below
std::cout << "I'm here" << std::endl;
std::terminate();
}
int main() {
std::thread driver(keep_moving);
std::thread wake_me(wake_me_up);
driver.join();
wake_me.join();
system("pause");
return 0;
}
As you can see thread 'keep_moving' counts from 0-20 in 20 seconds and then notifies the 'wake_me_up' thread which prints "I'm here" and then terminates. After notifying the thread the 'keep_moving' thread also terminates.
Please tell me if I'm terminating the threads in a proper way. When I run this code I get the following message:
terminate called without an active exception
I'm here
terminate called recursively
Aborted
Thank you.
No. The correct (and only correct in standard C++) way to terminate a thread is to return from its thread function.
std::terminate kills your entire process. Even if it only killed the current thread (i.e. behaved like the Win32 TerminateThread function, which you should never call!), it would not unwind the stack, not call destructors, and thus possibly leave some necessary cleanup unfinished (like releasing mutexes).
std::terminate is meant to be used on a critical failure where your program cannot possibly continue. The message "without an active exception" is because the primary use of terminate is to kill the program if the exception system fails, e.g. due to a nested exception, so the function by default looks for an active exception and prints information about it.

How can I propagate exceptions between threads?

We have a function which a single thread calls into (we name this the main thread). Within the body of the function we spawn multiple worker threads to do CPU intensive work, wait for all threads to finish, then return the result on the main thread.
The result is that the caller can use the function naively, and internally it'll make use of multiple cores.
All good so far..
The problem we have is dealing with exceptions. We don't want exceptions on the worker threads to crash the application. We want the caller to the function to be able to catch them on the main thread. We must catch exceptions on the worker threads and propagate them across to the main thread to have them continue unwinding from there.
How can we do this?
The best I can think of is:
Catch a whole variety of exceptions on our worker threads (std::exception and a few of our own ones).
Record the type and message of the exception.
Have a corresponding switch statement on the main thread which rethrows exceptions of whatever type was recorded on the worker thread.
This has the obvious disadvantage of only supporting a limited set of exception types, and would need modification whenever new exception types were added.
C++11 introduced the exception_ptr type that allows to transport exceptions between threads:
#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept>
static std::exception_ptr teptr = nullptr;
void f()
{
try
{
std::this_thread::sleep_for(std::chrono::seconds(1));
throw std::runtime_error("To be passed between threads");
}
catch(...)
{
teptr = std::current_exception();
}
}
int main(int argc, char **argv)
{
std::thread mythread(f);
mythread.join();
if (teptr) {
try{
std::rethrow_exception(teptr);
}
catch(const std::exception &ex)
{
std::cerr << "Thread exited with exception: " << ex.what() << "\n";
}
}
return 0;
}
Because in your case you have multiple worker threads, you will need to keep one exception_ptr for each of them.
Note that exception_ptr is a shared ptr-like pointer, so you will need to keep at least one exception_ptr pointing to each exception or they will be released.
Microsoft specific: if you use SEH Exceptions (/EHa), the example code will also transport SEH exceptions like access violations, which may not be what you want.
Currently, the only portable way is to write catch clauses for all the types of exceptions that you might like to transfer between threads, store the information somewhere from that catch clause and then use it later to rethrow an exception. This is the approach taken by Boost.Exception.
In C++0x, you will be able to catch an exception with catch(...) and then store it in an instance of std::exception_ptr using std::current_exception(). You can then rethrow it later from the same or a different thread with std::rethrow_exception().
If you are using Microsoft Visual Studio 2005 or later, then the just::thread C++0x thread library supports std::exception_ptr. (Disclaimer: this is my product).
If you're using C++11, then std::future might do exactly what you're looking for: it can automagically trap exceptions that make it to the top of the worker thread, and pass them through to the parent thread at the point that std::future::get is called. (Behind the scenes, this happens exactly as in #AnthonyWilliams' answer; it's just been implemented for you already.)
The down side is that there's no standard way to "stop caring about" a std::future; even its destructor will simply block until the task is done. [EDIT, 2017: The blocking-destructor behavior is a misfeature only of the pseudo-futures returned from std::async, which you should never use anyway. Normal futures don't block in their destructor. But you still can't "cancel" tasks if you're using std::future: the promise-fulfilling task(s) will continue running behind the scenes even if nobody is listening for the answer anymore.] Here's a toy example that might clarify what I mean:
#include <atomic>
#include <chrono>
#include <exception>
#include <future>
#include <thread>
#include <vector>
#include <stdio.h>
bool is_prime(int n)
{
if (n == 1010) {
puts("is_prime(1010) throws an exception");
throw std::logic_error("1010");
}
/* We actually want this loop to run slowly, for demonstration purposes. */
std::this_thread::sleep_for(std::chrono::milliseconds(100));
for (int i=2; i < n; ++i) { if (n % i == 0) return false; }
return (n >= 2);
}
int worker()
{
static std::atomic<int> hundreds(0);
const int start = 100 * hundreds++;
const int end = start + 100;
int sum = 0;
for (int i=start; i < end; ++i) {
if (is_prime(i)) { printf("%d is prime\n", i); sum += i; }
}
return sum;
}
int spawn_workers(int N)
{
std::vector<std::future<int>> waitables;
for (int i=0; i < N; ++i) {
std::future<int> f = std::async(std::launch::async, worker);
waitables.emplace_back(std::move(f));
}
int sum = 0;
for (std::future<int> &f : waitables) {
sum += f.get(); /* may throw an exception */
}
return sum;
/* But watch out! When f.get() throws an exception, we still need
* to unwind the stack, which means destructing "waitables" and each
* of its elements. The destructor of each std::future will block
* as if calling this->wait(). So in fact this may not do what you
* really want. */
}
int main()
{
try {
int sum = spawn_workers(100);
printf("sum is %d\n", sum);
} catch (std::exception &e) {
/* This line will be printed after all the prime-number output. */
printf("Caught %s\n", e.what());
}
}
I just tried to write a work-alike example using std::thread and std::exception_ptr, but something's going wrong with std::exception_ptr (using libc++) so I haven't gotten it to actually work yet. :(
[EDIT, 2017:
int main() {
std::exception_ptr e;
std::thread t1([&e](){
try {
::operator new(-1);
} catch (...) {
e = std::current_exception();
}
});
t1.join();
try {
std::rethrow_exception(e);
} catch (const std::bad_alloc&) {
puts("Success!");
}
}
I have no idea what I was doing wrong in 2013, but I'm sure it was my fault.]
You problem is that you could receive multiple exceptions, from multiple threads, as each could fail, perhaps from different reasons.
I am assuming the main thread is somehow waiting for the threads to end to retrieve the results, or checking regularly the other threads' progress, and that access to shared data is synchronized.
Simple solution
The simple solution would be to catch all exceptions in each thread, record them in a shared variable (in the main thread).
Once all threads finished, decide what to do with the exceptions. This means that all other threads continued their processing, which perhaps, is not what you want.
Complex solution
The more complex solution is have each of your threads check at strategic points of their execution, if an exception was thrown from another thread.
If a thread throws an exception, it is caught before exiting the thread, the exception object is copied into some container in the main thread (as in the simple solution), and some shared boolean variable is set to true.
And when another thread tests this boolean, it sees the execution is to be aborted, and aborts in a graceful way.
When all thread did abort, the main thread can handle the exception as needed.
An exception thrown from a thread will not be catchable in the parent thread. Threads have different contexts and stacks, and generally the parent thread is not required to stay there and wait for the children to finish, so that it could catch their exceptions. There is simply no place in code for that catch:
try
{
start thread();
wait_finish( thread );
}
catch(...)
{
// will catch exceptions generated within start and wait,
// but not from the thread itself
}
You will need to catch exceptions inside each thread and interpret exit status from threads in the main thread to re-throw any exceptions you might need.
BTW, in the absents of a catch in a thread it is implementation specific if stack unwinding will be done at all, i.e. your automatic variables' destructors may not even be called before terminate is called. Some compilers do that, but it's not required.
Could you serialize the exception in the worker thread, transmit that back to the main thread, deserialize, and throw it again? I expect that for this to work the exceptions would all have to derive from the same class (or at least a small set of classes with the switch statement thing again). Also, I'm not sure that they would be serializable, I'm just thinking out loud.
There is, indeed, no good and generic way to transmit exceptions from one thread to the next.
If, as it should, all your exceptions derive from std::exception, then you can have a top-level general exception catch that will somehow send the exception to the main thread where it will be thrown again. The problem being you loose the throwing point of the exception. You can probably write compiler-dependent code to get this information and transmit it though.
If not all your exception inherit std::exception, then you are in trouble and have to write a lot of top-level catch in your thread ... but the solution still hold.
You will need to do a generic catch for all exceptions in the worker (including non-std exceptions, like access violations), and send a message from the worker thread (i suppose you have some kind of messaging in place?) to the controlling thread, containing a live pointer to the exception, and rethrow there by creating a copy of the exception.
Then the worker can free the original object and exit.
See http://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_exception_ptr.html. It is also possible to write a wrapper function of whatever function you call to join a child thread, which automatically re-throws (using boost::rethrow_exception) any exception emitted by a child thread.