Receive async exception directly - c++

class ClassA
{
void running()
{
int count = 0;
m_worker_stop.store(true);
while (m_worker_stop.load() == false)
{
count++;
if (count == 10)
{
// Make exception
std::vector v(100000000000);
}
}
}
void start()
{
m_worker = std::async(std::launch::async, &ClassA::running, this);
}
void stop()
{
m_worker_stop.store(true);
if (m_worker.valid())
m_worker.get(); // catch exception in this point
}
std::future<void> m_worker;
std::atomic_bool m_worker_stop = { false };
}
class Main // this is single-ton Main class
{
...
void running()
{
try {
m_classA->start();
// Wait for external signal(ex. SIGINT, SIGTERM, ..)
while (true) { // signal check }
m_classA->stop();
}
catch(std::exception& e) {
// re-create throwed object
}
catch(...) {
// re-create throwed object
}
}
}
int main()
{
Manager::getInstance()::running();
return 0;
}
Hello, everyone.
The approximate structure of the program is as above.
In fact, I have not only classA but also many other objects such as B, C, and D.
(start() and stop() function is simillar !)
An exception was raised using std::vector v(1000000..)
However, it became a catch when stop() was activated.
What I actually want is to delete the classA object and re-create it if an exception occurs.
So I need to catch directly when exception was occured.
In this case, is any idea to get exception without wait for signals?

Here is one way of achieving the effect you want:
class Main // this is single-ton Main class
{
...
void running()
{
for (size_t i = 0; i < max_tries; ++i)
{
try {
m_classA->start();
// Wait for external signal(ex. SIGINT, SIGTERM, ..)
while (true) {
// signal check ...
}
m_classA->stop();
// path to happy ending :)
LOG("Main::running(): Operation successful.",
return;
}
catch(std::exception& e) {
LOG("Main::running(): Exception caught: message:\"{}\"", e.what());
}
catch(...) {
LOG("Main::running(): Unspecified exception caught, aborting.");
return; // Example of 'unrecoverable error'
}
// this part is only executed after an exception.
m_classA->shut_down(); // if you need some special shut down after an error.
m_classA.clear(); // this is redundant, but explicit (optional)
m_classA = MakeMeAnA(); // call our favorite A construction method.
}
// path to total failure :(
LOG("Main::running(): Exiting after {} failed attempts", max_tries);
}
private:
static constexpr size_t max_tries = 3;
};

Related

user defined exception handling

This is a c++ program to calculate average, and grade using 5 marks.
If marks entered are greater than 100 or less than 0, student exception should be thrown.
#include<iostream>
#include<exception>
using namespace std;
class lessex:public exception
{
public:
void what()
{
cout<<"Mark less than 0"<<endl;
}
};
class morex:public exception
{
public:
void what()
{
cout<<"Mark greater than 100"<<endl;
}
};
class student
{
string name;
string rollno;
int marks[5];
double avg;
char g;
public:
void get();
void aveg();
void grade();
void print();
};
void student::get()
{
cin>>name;
cin>>rollno;
for(int i=0;i<5;i++)
{
try{
cin>>marks[i];
if(marks[i]>100)
{
morex d;
throw d;
}
}
catch(morex &e)
{
/*e.what();*/
throw ;
}
try{
if(marks[i]<0)
{
lessex d;
throw d;
}
}
catch(lessex &e)
{
/*e.what();*/
throw ;
}
}
}
void student::aveg()
{
int sum=0;
for(int i=0;i<5;i++)
{
sum=sum+marks[i];
}
avg=sum/5;
}
void student::grade()
{
if(avg>90)
g='S';
else
g='Z';
}
void student::print()
{
cout<<name<<endl;
cout<<rollno<<endl;
cout<<g<<endl;
}
int main()
{
student s;morex e;lessex e1;
try{
s.get();
}
catch(morex &e)
{
e.what();
}
catch(lessex &e1)
{
e1.what();
}
s.aveg();
s.grade();
s.print();
return 0;
}
However, my program does not successfully exit after encountering exception in the main function.
Why is it continuing with s.aveg,grade,etc.
Why is my program not exiting after encountering exception-from main function? Why is it continuing with s.aveg,grade,etc.
You catch the exception, and then leave the catch block. Execution continues normally after that. Exceptions aren't re-thrown automatically at the end of a handler's block. That would maddening, what's the point of catching if you can't handle the error and continue running?
If you want the exception re-thrown, you need to add an explicit throw; in the handler. Like you already do in student::get(). Or just not have a try-catch block there. The program will terminate without "s.aveg,grade,etc." being executed.
Or, assuming you intent is not terminate, but to exit gracefully without executing other functions, you can do as user4581301 suggested. Move those function calls into the try block. That way, if an exception is thrown before their execution, they will not run before or after the handler.
You continue execution, without exiting, after catching the exception, and that's why the program isn't exiting.
First, you should follow the convention that what returns a string and doesn't print anything:
class lessex : public exception
{
public:
const char* what() const noexcept override
{
return "Mark less than 0";
}
};
class morex : public exception
{
public:
const char* what() const noexcept override
{
return "Mark greater than 100";
}
};
Then, you're overcomplicating things rather a lot in get;
void student::get()
{
cin >> name;
cin >> rollno;
for(int i = 0; i < 5; i++)
{
cin >> marks[i];
if (marks[i]>100)
{
throw morex();
}
if(marks[i]<0)
{
throw lessex();
}
}
}
and exceptions shouldn't be used like error codes and caught after each potentially throwing call, you normally write the "happy path" (the assumed-to-be-error-free path) and handle exceptions outside it:
int main()
{
try
{
// This part handles the normal case, assuming that all goes well.
student.s;
s.get();
s.aveg();
s.grade();
s.print();
}
// This part handles the exceptional case when something goes wrong.
catch (std::exception& ex)
{
std::cerr << ex.what();
}
}
(Your design is somewhat questionable since throwing from get can leave the object in an invalid state. You might want to rethink it.)
It is continuing because after you catch the exception you don't do anything about it. You have to specify what you would do inside the catch block when the specific exception is thrown.
Alternatively you could also move the other functions like s.aveg(); s.grade(); s.print(); inside try{
s.get();
}
This will prevent the aveg, grade and print functions from stop executing once an exeption is hit

terminate called recursively

As far as I know, terminate() is called when there is some problem with exception handling(usually it's just not caught).
What I got is just one error line terminate called recursively.
After googling for some time I found a lot of examples of
terminate called after throwing an instance of ... terminate called recursively
But it's not my case. As I don't have this hint about the exception type, I'm wondering what does this terminate called recursively mean by itself.
Sorry I can't provide the code, so any guess will be helpful.
I'm compiling with g++ 4.5.2 under Ubuntu 11.04.
Thanks a lot,
Alex.
Could be that some code throws an exception you don't catch, which means terminate will be called. Terminating the program means that object destructors might be called, and if there is an exception in one of them then terminate will be called "recursively".
I have encounter this question, it's maybe the error of your function in thread pool or thread.
Let's recur the terminate called recursively exception.
I am writing a thread pool with c++11, here is my code:
// blocking queue
template<typename T>
class SafeQueue{
public:
bool pop(T& value){
std::lock_guard<std::mutex> lock(mtx_);
if(queue_.empty())
return false;
value = queue_.front();
queue_.pop_front();
return true;
}
void push(T&& value){
std::lock_guard<std::mutex> lock(mtx_);
queue_.push_back(std::move(value));
}
bool empty(){
std::lock_guard<std::mutex> lock(mtx_);
return queue_.empty();
}
private:
std::mutex mtx_;
std::list<T> queue_;
};
typedef std::function<void()> Task;
typedef SafeQueue<Task> Tasks;
class ThreadPool{
public:
ThreadPool(uint32_t nums=5, bool start=false);
~ThreadPool();
void start();
void addTask(Task&& task);
void join();
void exit();
size_t getThreadNum(){return threadNums_;}
private:
Tasks tasks_;
std::vector<std::thread> threads_;
size_t threadNums_;
bool stop_;
};
ThreadPool::ThreadPool(uint32_t nums, bool start):
threadNums_(nums), stop_(false)
{
if(start)
this->start();
}
ThreadPool::~ThreadPool(){
stop_ = true;
}
void ThreadPool::start(){
auto lb_thread_fun = [this](){
while (!stop_){
Task task;
tasks_.pop(task);
// error from here, task maybe empty.
task();
}
};
for (int i = 0; i < threadNums_; ++i) {
threads_.push_back(std::thread(lb_thread_fun));
}
}
void ThreadPool::addTask(Task&& task){
tasks_.push(std::move(task));
}
void ThreadPool::join(){
for (auto& th:threads_) {
th.join();
}
}
void ThreadPool::exit(){
stop_ = true;
}
Test code as below:
#include "my_threadpool.h"
#include <iostream>
using std::cout;
using std::endl;
auto lb_dummy_dw = [](const std::string& url){
cout<<"start downloading: "<<url<<endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
cout<<"downloading success !!!!"<<url<<endl;
};
auto lb_dummy_sql = [](int id, const std::string& name){
cout<<"start select from db, id:" << id << ", name: "<<name<<endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
cout<<"select db success !!!!"<<endl;
};
void test_thread_pool(){
cout<<"create thread pool with 5 thread"<<endl;
xy::ThreadPool tp(5);
cout<<"add 3 * 2 task to thread pool"<<endl;
for (int i = 0; i < 3; ++i) {
tp.addTask(std::bind(lb_dummy_dw, "ww.xxx.com"));
tp.addTask(std::bind(lb_dummy_sql, i, "xy" + std::to_string(i)));
}
cout<<"start thread pool"<<endl;
tp.start();
tp.join();
}
int main(){
test_thread_pool();
return 0;
}
When you run the above code, you may get the below output:
create thread pool with 5 thread
add 3 * 2 task to thread pool
start thread pool
start downloading: ww.xxx.com
start select from db, id:0, name: xy0
start downloading: ww.xxx.com
start select from db, id:1, name: xy1
start downloading: ww.xxx.com
downloading success !!!!ww.xxx.com
start select from db, id:2, name: xy2
downloading success !!!!ww.xxx.com
downloading success !!!!ww.xxx.com
terminate called recursively
terminate called after throwing an instance of 'std::bad_function_call'
what():
You can see, it got terminate called recursively exception. Because, in the function start, the variable task maybe empty, so each thread in the thread pool throw bad_function_call exception.
void ThreadPool::start(){
auto lb_thread_fun = [this](){
while (!stop_){
Task task;
tasks_.pop(task);
// error from here, task maybe empty.
task();
}
};
for (int i = 0; i < threadNums_; ++i) {
threads_.push_back(std::thread(lb_thread_fun));
}
}
Task empty test code as below:
void test_task(){
Task task;
try{
task();
}catch (std::exception& e){
cout<<"running task, with exception..."<<e.what()<<endl;
return;
}
cout<<"ending task, without error"<<endl;
}
Output as below:
running task, with exception...bad_function_call

Error in exception handling with LLVM

I am trying to compile C++ code with CLANG++ as front end and backend as LLVM.
The version is 3.0.
There seems to be a problem with exception handling. Whenever the code throws an exception, the program just terminates with message that "Termination after throwing an exception".
Here is one of the sample code I tried with CLANG ++ .
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : virtual A {};
struct E : private B, public C, private D {};
extern "C" void abort ();
void fne (E *e)
{
throw e;
}
void check(E *e)
{
int caught;
caught = 0;
try { fne(e); }
catch(A *p) { caught = 1; if (p != e) abort();}
catch(...) { abort(); }
if (!caught) abort();
caught = 0;
try { fne(e); }
catch(B *p) { abort ();}
catch(...) { caught = 1; }
if (!caught) abort();
caught = 0;
try { fne(e); }
catch(C *p) { caught = 1; if (p != e) abort();}
catch(...) { abort(); }
if (!caught) abort();
caught = 0;
try { fne(e); }
catch(D *p) { abort ();}
catch(...) { caught = 1; }
if (!caught) abort();
return;
}
int main ()
{
E e;
check (&e);
check ((E *)0);
return 0;
}
I am quite new to LLVM so do not have much idea about it. Also does it have anything related to Exception Handling table generation by LLVM.
The above problem continues for any code.
I have compiled the above code on Linux machine.
Also I tried putting printf on every catch clause but no response. So it seems that when exception was thrown , no matching catch was found for the exception and it led to call of terminate funciton
Seeing your other question... If you're on arm/linux - then such result is expected. The support for EH is not finished there, so, it might be arbitrary broken.

How to get the exception reported to boost::future?

If I use Boost futures, and the future reports true to has_exception(), is there any way to retrieve that exception? For example, here is the following code:
int do_something() {
...
throw some_exception();
...
}
...
boost::packaged_task task(do_something);
boost::unique_future<int> fi=task.get_future();
boost::thread thread(boost::move(task));
fi.wait();
if (fi.has_exception()) {
boost::rethrow_exception(?????);
}
...
The question is, what should be put in the place of "?????"?
According to http://groups.google.com/group/boost-list/browse_thread/thread/1340bf8190eec9d9?fwc=2, you need to do this instead:
#include <boost/throw_exception.hpp>
int do_something() {
...
BOOST_THROW_EXCEPTION(some_exception());
...
}
...
try
{
boost::packaged_task task(do_something);
boost::unique_future<int> fi=task.get_future();
boost::thread thread(boost::move(task));
int answer = fi.get();
}
catch(const some_exception&)
{ cout<< "caught some_exception" << endl;}
catch(const std::exception& err)
{/*....*/}
...

How to implement final conditions properly?

This is what I'm trying to do (this is a simplification of a real project):
int param;
int result;
void isolated(int p) {
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
} catch (...) {
throw "problems..";
}
}
I can't change the way process() works, since this function is not created in the project and is a third-party function. It works with global variables param and result and we can't change this.
The problem appears when isolated() is called back from process() with another parameter. I want to catch this situation, but don't know how to do it, since finally is absent in C++. I feel that I should use RAII technique, but can't figure out how to do it in this case properly.
This is how I can make it with code duplication:
int param;
int result;
void isolated(int p) {
static bool running;
if (running) {
throw "you can't call isolated() from itself!";
}
running = true;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
running = false;
} catch (...) {
running = false; // duplication!
throw "problems..";
}
}
"finally" like situations are handled in C++ using guard objects, that do their finally thing in the destructor. This is IMHO much more powerful approach, because you have to analyze the situation to finalize in order to create a reuseable object. In this case, we need to make process rentrant, because parameters and returns are passed in globals. The solution is to save their values on entry and restore them on exit:
template<class T>
class restorer
{
T &var; // this is the variable we want to save/restore
T old_value; // the old value
restorer(const restorer&);
void operator=(const restorer&);
public:
restorer(T &v) : var(v), old_value(v) {}
~restorer() { var=old_value; }
};
int param;
int result;
int isolated(int p) {
restorer<int> rest_param(param);
restorer<int> rest_result(result);
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
Maybe I didn't get it right, but why don't you use a flag? You want to know when the isolated() is called from the process(), right?
int isolated(int p) {
static int execDeep = 0;
execDeep++;
// your code here
execDeep--;
}
Now you can check 'execDeep' value, > 1 means it is called from the process() while still being executed.
I still don't quite sure how finally is related here, but you could try Boost.ScopeExit if you want to avoid creating a scope guard structure yourself.
Example:
#include <boost/scope_exit.hpp>
#include <cstdio>
int isolated(int p) {
static bool running = false;
if (running) {
printf("Throwing %d\n", p);
throw p;
}
printf("Starting %d\n", p);
running = true;
BOOST_SCOPE_EXIT( (p)(&running) ) { // <--
printf("Stopping %d\n", p); // <--
running = false; // <--
} BOOST_SCOPE_EXIT_END // <--
// ...
if (p)
isolated(p*10);
// ...
printf("Returing %d\n", p);
return 4;
}
int main() {
printf(">> first\n");
isolated(0);
printf(">> second\n");
try {
isolated(1);
printf(">> third (should not be printed.)\n");
} catch(int p) {
printf("Caught %d\n", p);
}
isolated(0);
printf(">> fourth\n");
return 0;
}
Result:
>> first
Starting 0
Returing 0
Stopping 0
>> second
Starting 1
Throwing 10
Stopping 1
Caught 10
Starting 0
Returing 0
Stopping 0
>> fourth
Could this work?
int save = -10000000000;
int param;
int result;
int isolated(int p) {
if (save != -10000000000)
{
// run the other condition
}
else
{
save = p;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
}
If I understand correctly, you want to automatically set the running flag to false at the end of function. If that is the requirement then you can use the ScopeGuard approarch mentioned in the link.