Boost interrupted exception not caught in MAC environment [duplicate] - c++

I want to interrupt a thread using boost::thread interrupt(). I have the following code which doesn't throw boost::thread_interrupted& exception:
int myClass::myFunction (arg1, arg2) try{
//some code here
do {
boost::this_thread::interruption_point();
//some other code here
} while (counter != 20000);
}catch (boost::thread_interrupted&) {
cout << "interrupted" << endl;
}
If I replace boost::this_thread::interruption_point() with boost::this_thread::sleep( boost::posix_time::milliseconds(150)) exception is throw and interrupt works as it should.
Can someone explain why boost::this_thread::interruption_point() doesn't throw the expected exception?

As the commenter noted, there's no way to rule out a simple race condition (depends a lot on your architecture and load on the CPU). The fact adding an explicit sleep "helps" underlines this.
Are you running on a single-core system?
Here's a simple selfcontained example in case you spot something you are doing differently. See this simple tester:
#include <iostream>
#include <boost/thread.hpp>
struct myClass {
int myFunction(int arg1, int arg2);
};
int myClass::myFunction (int arg1, int arg2)
{
int counter = 0;
try
{
//some code here
do {
boost::this_thread::interruption_point();
//some other code here
++counter;
} while (counter != 20000);
} catch (boost::thread_interrupted&) {
std::cout << "interrupted" << std::endl;
}
return counter;
}
void treadf() {
myClass x;
std::cout << "Returned: " << x.myFunction(1,2) << "\n";
}
int main()
{
boost::thread t(treadf);
//t.interrupt(); // UNCOMMENT THIS LINE
t.join();
}
It prints
Returned: 20000
Or, if you uncomment the line with t.interrupt()
interrupted
Returned: 0
On my i7 system. See it Live On Coliru

Related

Does exception belong to threads or process in C++?

Let's say we have two running threads that both would throw exceptions and there are exception handlers in these threads.
Would C++ be able to handle that, not running into terminated or undefined behavior.
Is it correct that exception belongs to per thread, and each thread can have no more than one exception at a time?
Is it correct that exception belongs to per thread
That is correct.
and each thread can have no more than one exception at a time?
A thread can have more than one active exception. See int uncaught_exceptions() noexcept:
Detects how many exceptions in the current thread have been thrown or rethrown and not yet entered their matching catch clauses.
E.g.:
#include <iostream>
#include <stdexcept>
void f() {
throw std::runtime_error("error");
}
struct A {
~A() {
std::cout << "uncaught_exceptions: " << std::uncaught_exceptions() << '\n';
}
};
struct B {
~B() {
try {
A a;
f();
}
catch(std::exception&) {}
}
};
int main() {
try {
B b;
f();
}
catch(std::exception&) {}
}
Outputs:
uncaught_exceptions: 2
The following example shows that the exception handler is using the stack of thread t1 which made a division by zero exception. It means that exception belongs to per thread.
// g++ -std=c++0x -pthread -fnon-call-exceptions main.cpp
#include <iostream>
#include <thread>
#include <signal.h>
void handler(int signo) {
int handler_local_var;
std::cout << &handler_local_var << " in stack of handler" << std::endl;
throw signo;
}
void thread1(std::string msg) {
int t1_local_var;
std::cout << &t1_local_var << " in stack of " << msg << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
signal(SIGFPE,handler);
try {
int x = 100 / 0; /* ignore warning: division by zero [-Wdiv-by-zero] */
}
catch (...) {
std::cout << "caught" << std::endl;
}
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
void thread2(std::string msg) {
int t2_local_var;
std::cout << &t2_local_var << " in stack of " << msg << std::endl;
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
int main() {
int main_local_var;
std::cout << &main_local_var << " in stack of main" << std::endl;
std::thread t1(thread1,"t1");
std::thread t2(thread2,"t2");
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2)); /* Ctrl-C to stop */
}
return 0;
}
Test result:
$ ./a.out
0x7ffee7fea788 in stack of main
0x7f0b54b92d68 in stack of t2
0x7f0b55393d54 in stack of t1
0x7f0b55393754 in stack of handler
caught

Different seh filtering in x86 and x64

I am implementing logging of error message (It includes information of exception backtrace). I asked similar question how to do this at Reliable way to print exception backtrace in catch handler?. I decided to check out callstacks at x86 and x64 platforms. Result of stack comparisons surprised me. Here is my program:
#include <iostream>
#include <Windows.h>
using namespace std;
struct A
{
};
void foo3()
{
throw A();
}
void foo2()
{
foo3();
}
void foo1()
{
foo2();
}
void foo()
{
try
{
foo1();
}
catch(...)
{
cout << "exception rethrowing" << endl;
throw;
}
}
int seh_filter(_EXCEPTION_POINTERS* exception)
{
cout << "SEH FILTER" << endl;
return EXCEPTION_EXECUTE_HANDLER;
}
int main(void)
{
__try
{
foo();
}
__except(seh_filter(GetExceptionInformation()))
{
cout << "SEH catch handler" << endl;
}
return 0;
}
I set breakpoint at seh_filter to explore backtrace and ran debug builds. Here is images:
It seems like I cannot print full call stack on x64 platform. What's going on? I cannot understand why were callstacks changed so dramatically? I am using msvc2013 on Windows 10.

std::async and std::shared_future causes the program to fall

I am trying to run some function in asynchronous manner. For this purpose I wrote class called Core where I use std::async to run function in different thread and std::shared_future<int> to wait for this thread and possibly to get future result. This is code of test program:
#include <iostream>
#include <future>
class Core : public std::enable_shared_from_this<Core>
{
public:
Core()
: isRunning_(false) {
};
~Core() {
isRunning_ = false;
if (f_.valid())
{
f_.wait();
std::cout << "Result is: " << f_.get() << std::endl;
}
};
void Start() {
isRunning_ = true;
auto self(shared_from_this());
f_ = std::async(std::launch::async, [self, this]() {
try {
while (true) {
if (!isRunning_)
break;
std::cout << "Boom" << std::endl; // Error occurs here
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
catch (const std::exception& e) {
std::cerr << "Loop error:" << e.what();
}
return 999;
});
}
private:
std::shared_future<int> f_;
std::atomic<bool> isRunning_;
};
int main()
{
try {
std::shared_ptr<Core> load(new Core);
load->Start();
throw std::runtime_error("Generate error"); // Added in order to generate error
}
catch (const std::exception& e) {
std::cout << "Error occurred: " << e.what();
}
return 0;
}
Each time when I start this program it crashes at this line:
std::cout << "Boom" << std::endl; // Error occurs here
with this error:
That is debugger error and call stack which I managed to get during debugging:
Looks like Core destructor function doesn't call at all. Why is it happens? weird!!!
Could you tell me where is my mistake? Thanks.
When main thread returns from main() it starts tearing down the environment before terminating the whole process. All this while background thread is accessing objects there are being destroyed or have been destroyed already.
I am not sure what you are triying to achieve, but you are doing something wrong:
Your lambda should execute some work and return immediately after it is done e.g. you should never loop forever.
Your main thread should wait for your future to complete by calling std::future<T>::get().

boost::this_thread::interruption_point() doesn't throw boost::thread_interrupted& exception

I want to interrupt a thread using boost::thread interrupt(). I have the following code which doesn't throw boost::thread_interrupted& exception:
int myClass::myFunction (arg1, arg2) try{
//some code here
do {
boost::this_thread::interruption_point();
//some other code here
} while (counter != 20000);
}catch (boost::thread_interrupted&) {
cout << "interrupted" << endl;
}
If I replace boost::this_thread::interruption_point() with boost::this_thread::sleep( boost::posix_time::milliseconds(150)) exception is throw and interrupt works as it should.
Can someone explain why boost::this_thread::interruption_point() doesn't throw the expected exception?
As the commenter noted, there's no way to rule out a simple race condition (depends a lot on your architecture and load on the CPU). The fact adding an explicit sleep "helps" underlines this.
Are you running on a single-core system?
Here's a simple selfcontained example in case you spot something you are doing differently. See this simple tester:
#include <iostream>
#include <boost/thread.hpp>
struct myClass {
int myFunction(int arg1, int arg2);
};
int myClass::myFunction (int arg1, int arg2)
{
int counter = 0;
try
{
//some code here
do {
boost::this_thread::interruption_point();
//some other code here
++counter;
} while (counter != 20000);
} catch (boost::thread_interrupted&) {
std::cout << "interrupted" << std::endl;
}
return counter;
}
void treadf() {
myClass x;
std::cout << "Returned: " << x.myFunction(1,2) << "\n";
}
int main()
{
boost::thread t(treadf);
//t.interrupt(); // UNCOMMENT THIS LINE
t.join();
}
It prints
Returned: 20000
Or, if you uncomment the line with t.interrupt()
interrupted
Returned: 0
On my i7 system. See it Live On Coliru

boost disable_interruption not preventing thread_interrupted

I am trying to prevent interruption of a thread while it is in a particular scope. However, using boost::this_thread::disable_interruption di() does not seem to have any effect.
#include <boost/thread.hpp>
#include <iostream>
void worker() {
std::cout << "START" << std::endl;
for(;;) {
{
boost::this_thread::disable_interruption di();
try {
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
catch(boost::thread_interrupted & e) {
assert( false );
}
}
try {
boost::this_thread::interruption_point();
}
catch(boost::thread_interrupted & e) {
break;
}
}
std::cout << "END" << std::endl;
}
int main() {
boost::thread thread(&worker);
thread.interrupt();
thread.join();
}
The documentation appears to imply that boost::this_thread::sleep() will not throw boost::thread_interrupted while di is in scope.
What am I doing wrong?
You should remove parenthesis in the following line:
//boost::this_thread::disable_interruption di();
boost::this_thread::disable_interruption di;
Instead of creating disable_interruption object, you declared function di.