Is std::uncaught_exceptions useful for avoiding all exceptions? [duplicate] - c++

This question already has answers here:
How to catch segmentation fault in Linux?
(5 answers)
Catching access violation exceptions?
(8 answers)
Closed 6 years ago.
I need to catch segmentation fault and other unknown exceptions in my application. But I do not know how I can do that!
Can I use std::uncaught_exceptions for this aim?

Can I use std::uncaught_exceptions for this aim?
Consider this code:
int main(int argc, char* argv[])
{
int *val = NULL;
*val = 1;
std::cout << "uncaught: " << std::uncaught_exceptions() << std::endl;
return 0;
}
This will likely cause a segmentation fault and nothing will be output.
I need to catch segmentation fault and other unknown exceptions in my application. But I do not know how I can do that!
Exception handling in C++ can be done through the try-catch block, and you could use the std::signal function to catch certain errors like SIGSEGV, SIGFPE, or SIGILL, example:
#include <iostream>
#include <exception>
#include <csignal>
#include <cstdio>
extern "C" {
void sig_fn(int sig)
{
printf("signal: %d\n", sig);
std::exit(-1);
}
}
int main(int argc, char* argv[])
{
int *val = NULL;
std::signal(SIGSEGV, sig_fn);
try {
*val = 1;
} catch (...) {
std::cout << "..." << std::endl;
}
if (std::uncaught_exception()) {
std::cout << "uncaught" << std::endl;
}
std::cout << "return" << std::endl;
return 0;
}
But you should note that this type of exception handling is really meant to do clean-up and shutdown, not necessarily catch and release; take this code for example:
#include <iostream>
#include <exception>
#include <csignal>
#include <cstdio>
extern "C" {
void sig_fn(int sig)
{
printf("signal: %d\n", sig);
}
}
int main(int argc, char* argv[])
{
int *val = NULL;
std::signal(SIGSEGV, sig_fn);
while (true) {
try {
*val = 1;
} catch (...) {
std::cout << "..." << std::endl;
}
}
if (std::uncaught_exception()) {
std::cout << "uncaught" << std::endl;
}
std::cout << "return" << std::endl;
return 0;
}
This code will cause and catch the segmentation fault forever!
If you are trying to catch a segmentation fault, you need to investigate why the segmentation fault (or any error for that matter) happened in the first place and correct that issue; using the above code as an example:
int *val = NULL;
if (val == NULL) {
std::cout << "Handle the null!" << std::endl;
} else {
*val = 1;
}
For further reading: here is a SO Q&A on what a segfault is, as well, here is the Wiki on it, and MIT has some tips on handling and debugging segfaults too.
Hope that can help.

Related

Throwing Clear Exception in a Multithreaded Context with a proram STOP

I have a program that throws in another thread as follows:
#include <iostream>
#include <stdexcept>
#include <thread>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw(std::runtime_error("OP ERROR"));
};
int main(int argc, char* argv[])
{
//throw(std::runtime_error("MAIN ERROR"));
std::thread t(op);
t.join();
std::cout << "MAIN HELLO WORLD" << std::endl;
};
I want my program to print a clear error message and stop. I know I can use std::abort or std::terminate, however the error message is not clear and does not contain the log "OP ERROR".
Could you please help me code a program that when fails exits and logs a clear error message. std::future does not work too when I tried a try, catch block?
Are you looking for something like this?
#include <iostream>
#include <stdexcept>
#include <thread>
#include <future>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw(std::runtime_error("OP ERROR. File: " __FILE__ ", Line: "+ std::to_string(__LINE__)));
};
int main(int argc, char* argv[])
{
//throw(std::runtime_error("MAIN ERROR"));
auto res = std::async(op);
try {
res.get();
} catch(const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return -1;
}
std::cout << "MAIN HELLO WORLD" << std::endl;
}
If you want to output errors for all threads without returning exceptions to main thread, you can setup your own version of terminate().
#include <iostream>
#include <cstdlib>
#include <exception>
#include <thread>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw(std::runtime_error("OP ERROR"));
}
void my_terminate()
{
auto eptr = std::current_exception();
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch(const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
std::abort();
}
int main(int argc, char* argv[])
{
std::set_terminate(my_terminate);
//throw(std::runtime_error("MAIN ERROR"));
std::thread t(op);
t.join();
std::cout << "MAIN HELLO WORLD" << std::endl;
}
For some reason MSVC uses per-thread handlers, and for it to work you need to call set_termnate() in every thread separatelly.
To avoid the call to std::terminate, make sure exceptions don't "leak" outside the thread function.
void op()
{
try {
std::cout << "OP HELLO WORLD" << std::endl;
throw std::runtime_error("OP ERROR");
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
exit(1);
}
}
If you want to automatically see the exception's file and line number, in C++ it is not generally possible.
If you want to catch all exceptions in a single place in the main thread, you need to catch them and pass them to the main thread. There's a useful wrapper utility std::packaged_task which gives back a future on which you can wait for the result or an exception.
#include <iostream>
#include <stdexcept>
#include <thread>
#include <future>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw std::runtime_error("OP ERROR");
}
int main(int argc, char* argv[])
{
try {
std::packaged_task<void()> task{&op};
auto result = task.get_future();
std::thread t{std::move(task)};
t.join();
result.get();
std::cout << "MAIN HELLO WORLD" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}

XercesDOMParser scoped instantiation causes segfault

I have just come across a strange behavior of the Xerces-C library which I do not understand. The following code, which has already been seen in loads of examples, works for me:
#include <iostream>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
using namespace std;
using namespace xercesc;
int main (int argc, char* argv[])
{
try {
XMLPlatformUtils::Initialize ();
XercesDOMParser* parser = new XercesDOMParser ();
// here one might want to add some useful operations
delete parser;
XMLPlatformUtils::Terminate ();
}
catch (...) {
cout << "caught some exception" << endl;
}
return 0;
}
Surely, this code does not do many meaningful things. But it runs and in particular terminates cleanly.
Now, I was trying to avoid the new/delete and switch to a scoped object, like so:
#include <iostream>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
using namespace std;
using namespace xercesc;
int main (int argc, char* argv[])
{
try {
XMLPlatformUtils::Initialize ();
XercesDOMParser parser;
// here one might want to add some useful operations
XMLPlatformUtils::Terminate ();
}
catch (XMLException& exc) {
cout << "caught an XMLException" << endl;
}
catch (...) {
cout << "caught an exception" << endl;
}
return 0;
}
This or similar code has also been seen many times. However, when I run it, it creates a segfault after (?) XMLPlatformUtils::Terminate() (that's at least, what my debugger is suggesting). Still, I have successfully worked with a parser object created in that way. And if I omit the call to Terminate(), I see my process terminate cleanly.
Does anyone have a clue what I am doing wrong here?
Paul's comment already gave the correct answer and his explanation why does make sense. So for completeness, here is the code that actually works (note the explicitly created inner scope):
#include <iostream>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
using namespace std;
using namespace xercesc;
int main (int argc, char* argv[])
{
try {
XMLPlatformUtils::Initialize ();
{
XercesDOMParser parser;
// here one might want to add some useful operations
}
XMLPlatformUtils::Terminate ();
}
catch (XMLException& exc) {
cout << "caught an XMLException" << endl;
}
catch (...) {
cout << "caught an exception" << endl;
}
return 0;
}
Thank you Paul!

I found something while playing with VS2017

While I'm trying to learn throw catch I just compiled my code and I found this output what does that mean?
#include "stdafx.h"
#include <iostream>
using namespace std;
void MightGoWrong() {
bool error = true;
if (error) {
throw 8;
}
// -------------------------
int main()
{
cout << MightGoWrong;
return 0;
}
And output is : 012211A4 what does that mean?
Output
Code
You are not calling your function.
cout << MightGoWrong; is simply printing the address of the function. To call it you should do cout << MightGoWrong();.

Catch all possible errors program

I am new to C++ and wondering how I could catch all possible errors that could happen in my program during run-time. This is for debugging reasons only. To solve possible errors, I would like to have a look at them first.
This would be my idea of how to catch possible errors in a program. I do not throw exceptions, but would like to catch possible errors directly.
#include <iostream>
#include <exception>
#include <stdexcept>
int doBadStuf(int i)
{
// go out of bounce, or make other mistakes
return 10 / i;
}
int main()
{
try
{
int i = doBadStuf(0);
}
catch (std::exception &e)
{
std::cerr << e.what() << '\n';
}
catch (...)
{
std::cerr << "something else";
}
}

Notification about exceptions in QtConcurrent::run

I know it doesn't make sense to actually handle an exception thrown in a different thread, but is there some way I can get notified that at least an exception occurred? E.g. something like
#include <QtConcurrentRun>
#include <iostream>
#include <stdexcept>
void MyFunction()
{
// std::cout << "MyFunction()" << std::endl;
throw std::runtime_error("Test exception.");
}
int main()
{
try
{
QtConcurrent::run(MyFunction);
}
catch(...)
{
std::cout << "Exception caught!" << std::endl;
}
}
exits quietly, even though an exception occurred. This is sometimes very confusing when the exception comes from deep down in the call stack somewhere.
------------EDIT-------------
I tried to write a wrapper like UmNyobe suggested, but I must be doing something wrong with the function pointers?
#include <QtConcurrentRun>
#include <QFutureWatcher>
#include <QObject>
#include <iostream>
#include <stdexcept>
void MyFunction()
{
// std::cout << "MyFunction()" << std::endl;
throw std::runtime_error("Test exception.");
}
template<typename TFirstParam, typename... TParams>
bool ExceptionWrapper(TFirstParam firstParam, TParams&& ...params)
{
// Here 'firstParam' should be a function pointer, and 'params' are the arguments
// that should be passed to the function
try
{
firstParam(params...);
}
catch(...)
{
std::cout << "Exception caught!" << std::endl;
return false; // failure
}
return true; // success
}
struct MyClass : public QObject
{
Q_OBJECT
MyClass()
{
connect(&this->FutureWatcher, SIGNAL(finished()), this, SLOT(slot_finished()));
}
void DoSomething()
{
void (*myFunctionPointer)() = MyFunction;
bool (*functionPointer)(decltype(myFunctionPointer)) = ExceptionWrapper;
QFuture<bool> future = QtConcurrent::run(functionPointer);
this->FutureWatcher.setFuture(future);
}
QFutureWatcher<void> FutureWatcher;
void slot_finished()
{
std::cout << "Finished" << std::endl;
if(!this->FutureWatcher.result())
{
std::cout << "There was an error!" << std::endl;
}
}
};
#include "ExceptionWrapper.moc"
int main()
{
MyClass myClass = new MyClass;
myClass->DoSomething();
}
The error I get is on this line:
QFuture<bool> future = QtConcurrent::run(functionPointer);
error: no matching function for call to 'run(bool (*&)(void (*)()))'
I know it doesn't make sense to actually handle an exception thrown in a different thread, but is there some way I can get notified that at least an exception occurred?
You can handle it by using the future returned from QtConcurrent::run. See this page for details. When you collect on the future, any unhandled exceptions will be rethrown. You can make a simple wrapper class to capture an exception and examine it in the receiving thread.
#include <QtGui>
#include <iostream>
#include <stdexcept>
class MyException : public QtConcurrent::Exception
{
public:
MyException(std::exception& err) : e(err) {}
void raise() const { throw *this; }
Exception* clone() const { return new MyException(*this); }
std::exception error() const { return e; }
private:
std::exception e;
};
// first concurrent function
int addFive(int n)
{
try
{
throw std::runtime_error("kablammo!");
//throw -1;
return n + 5;
}
catch (std::exception& e)
{
throw MyException(e);
}
}
// second concurrent function
void myVoidFunction()
{
try
{
throw std::runtime_error("oops!");
//throw -1;
}
catch (std::exception& e)
{
throw MyException(e);
}
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QFuture<int> f1 = QtConcurrent::run(addFive, 50);
try
{
int r = f1.result();
std::cout << "result = " << r << std::endl;
}
catch (MyException& me)
{
std::cout << me.error().what() << std::endl;
}
catch (QtConcurrent::UnhandledException&)
{
std::cout << "unhandled exception in addFive\n";
}
QFuture<void> f2 = QtConcurrent::run(myVoidFunction);
try
{
// result() not available for QFuture<void>, use waitForFinished() to
// block until it's done.
f2.waitForFinished();
std::cout << "myVoidFunction finished\n";
}
catch (MyException& me)
{
std::cout << me.error().what() << std::endl;
}
catch (QtConcurrent::UnhandledException&)
{
std::cout << "unhandled exception in myVoidFunction\n";
}
QWidget w;
w.show();
return app.exec();
}
It seems that if an exception is thrown, the isCanceled() of an associated QFutureWatcher returns true:
#include <QApplication>
#include <QtConcurrentRun>
#include <QFutureWatcher>
#include <iostream>
#include <stdexcept>
void MyFunction()
{
std::cout << "MyFunction()" << std::endl;
throw std::runtime_error("Test exception.");
}
struct MyClass : public QObject
{
Q_OBJECT
public:
MyClass()
{
connect(&this->FutureWatcher, SIGNAL(finished()), this, SLOT(slot_finished()));
}
void DoSomething()
{
QFuture<void> future = QtConcurrent::run(MyFunction);
this->FutureWatcher.setFuture(future);
}
QFutureWatcher<void> FutureWatcher;
public slots:
void slot_finished()
{
std::cout << "Finished" << std::endl;
if(this->FutureWatcher.isCanceled())
{
std::cout << "There was an error!" << std::endl;
}
else
{
std::cout << "Success!" << std::endl;
}
}
};
#include "Exception.moc"
int main(int argc, char*argv[])
{
MyClass myClass;
myClass.DoSomething();
QApplication app(argc, argv);
return app.exec();
}
--------- Edit (Simplified version of Gordon Freeman's answer) ---------
The exceptions seem to be re-thrown even without using a QtConcurrent::Exception subclass?
#include <QtGui>
#include <iostream>
#include <stdexcept>
// non-void concurrent function
int addFive(int n)
{
throw std::runtime_error("addFive throw!");
return n+5;
}
// void concurrent function
void myVoidFunction()
{
throw std::runtime_error("myVoidFunction throw!");
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QFuture<int> f1 = QtConcurrent::run(addFive, 50);
try
{
int r = f1.result();
std::cout << "result = " << r << std::endl;
}
catch (...)
{
std::cout << "exception in addFive." << std::endl;
}
QFuture<void> f2 = QtConcurrent::run(myVoidFunction);
try
{
// result() not available for QFuture<void>, use waitForFinished() to
// block until it's done.
f2.waitForFinished();
std::cout << "myVoidFunction finished\n";
}
catch (...)
{
std::cout << "exception in myVoidFunction\n";
}
QWidget w;
w.show();
return app.exec();
}
The good thing about QtConcurrent::run is that it accepts functions with a return value.
My two cents : catch the exception as early as possible...
disclaimer : I am really bad with exceptions in c++ :D
The code which is called in a different thread should return a value. In the case of a void function, or an existing function which doesn't catch exception you can define a wrapper (generic or not). For instance
int exceptionwrapper(){
int exception = 0;
try
{
myFunction();
}
catch(...){
exception = 1;
std::cout << "Exception caught!" << std::endl;
}
return exception;
}
Then later
QFuture<int> future = QtConcurrent::run(exemptionwrapper);
futurewatcher.setFuture(future);
You just use the future watcher to be able to examine the future later, when the function is over.