I did this test to see what happened:
try
{
int *x = 0;
*x = 1234;
}
catch(...)
{
cout << "OK";
}
But it throws a segfault, why does it not catch the segfault?
No you can`t.
A SEGFAULT isn't a regular exception.
The code you show is simply undefined behavior, and anything may be happen. There's no guarantee it ends up throwing an exception.
This answer is very specific to WINDOWS.
You can use Structured Exception Handling.
You have to call "SetUnhandledExceptionFilter"
https://msdn.microsoft.com/en-us/library/ms680634(v=vs.85).aspx
usage prototype:
You have to register a function at the beginning of application
SetUnhandledExceptionFilter(UnhandledExceptionFilterFunction);
Define your registered function, Handle your business.
Usually people collect coredumps and send Emails to dev team.
LONG WINAPI UnhandledExceptionFilterFunction(PEXCEPTION_POINTERS exception)
{
// The exception information is available in PEXCEPTION_POINTERS
}
Refer below link for PEXCEPTION_POINTERS
https://msdn.microsoft.com/en-us/library/windows/desktop/ms679331(v=vs.85).aspx
Here is the list of exception records that you get in "PEXCEPTION_POINTERS". The first one is "EXCEPTION_ACCESS_VIOLATION" (in LINUX terms SEGFAULT)
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082(v=vs.85).aspx
Related
Question:
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)? Or can I just explicitly call something like exit(EXIT_FAILURE) instead?
What I'm Currently Doing:
I'm working on a game project and am trying to figure out the best way to terminate the program in the case of an error that calls for such an action. For example, in the case the textures can't be loaded I display an error message and terminate the program.
I'm currently doing this with exceptions like so:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
return 0;
}
All but bad_alloc are my own defined exceptions derived from runtime_error.
I don't need any manual resource cleanup and I'm using std::unique_ptr for any dynamic allocation. I just need to display the error message and close the program.
Research/Alternatives to Exceptions:
I've looked up a lot of posts on SO and other places and have seen others say anything from don't use exceptions, to use exceptions but your using them wrong. I've also looked up explicitly calling something like exit().
Using exit() sounds nice but I read it won't go back through the call stack up to main cleaning everything up (if I can find this again I'll post the link). Additionally, according to http://www.cplusplus.com/reference/cstdlib/exit/ this should not be used if multiple threads are active. I do expect to be creating a second thread for a short time at least once, and an error could occur in that thread.
Not using exceptions was mentioned in some replies here in relation to games https://gamedev.stackexchange.com/questions/103285/how-industy-games-handle-their-code-errors-and-exceptions
Use exceptions was discussed here: http://www.quora.com/Why-do-some-people-recommend-not-using-exception-handling-in-C++
There are a number of other sources I've read but those were the most recent I looked at.
Personal Conclusion:
Due to my limited experience of working with error handling and using exceptions, I'm not sure if I'm on the right track. I've chosen the route of using exceptions based on the code I posted above. If you agree that I should tackle those cases with exceptions, am I using it correctly?
It's generally considered good practice to let all exceptions propagate through to main. This is primarily because you can be sure the stack is properly unwound and all destructors are called (see this answer). I also think it's more organised to do things this way; you always known where your program will terminate (unless the program crashes). It's also facilitates more consistent error reporting (a point often neglected in exception handling; if you can't handle the exception, you should make sure your user knows exactly why). If you always start with this basic layout
int main(int argc, const char **argv)
{
try {
// do stuff
return EXIT_SUCCESS;
} catch (...) {
std::cerr << "Error: unknown exception" << std::endl;
return EXIT_FAILURE;
}
}
then you won't go far wrong. You can (and should) add specific catch statements for better error reporting.
Exceptions when multithreading
There are two basic ways of executing code asynchronously in C++11 using standard library features: std::async and std::thread.
First the simple one. std::async will return a std::future which will capture and store any uncaught exceptions thrown in the given function. Calling std::future::get on the future will cause any exceptions to propagate into the calling thread.
auto fut = std::async(std::launch::async, [] () { throw std::runtime_error {"oh dear"}; });
fut.get(); // fine, throws exception
On the other hand, if an exception in a std::thread object is uncaught then std::terminate will be called:
try {
std::thread t {[] () { throw std::runtime_error {"oh dear"};}};
t.join();
} catch(...) {
// only get here if std::thread constructor throws
}
One solution to this could be to pass a std::exception_ptr into the std::thread object which it can pass the exception to:
void foo(std::exception_ptr& eptr)
{
try {
throw std::runtime_error {"oh dear"};
} catch (...) {
eptr = std::current_exception();
}
}
void bar()
{
std::exception_ptr eptr {};
std::thread t {foo, std::ref(eptr)};
try {
// do stuff
} catch(...) {
t.join(); // t may also have thrown
throw;
}
t.join();
if (eptr) {
std::rethrow_exception(eptr);
}
}
Although a better way is to use std::package_task:
void foo()
{
throw std::runtime_error {"oh dear"};
}
void bar()
{
std::packaged_task<void()> task {foo};
auto fut = task.get_future();
std::thread t {std::move(task)};
t.join();
auto result = fut.get(); // throws here
}
But unless you have good reason to use std::thread, prefer std::async.
There's nothing wrong with catching unrecoverable errors and shutting down your program this way. In fact, it's how exceptions should be used. However, be careful not to cross the line of using exceptions to control the flow of your program in ordinary circumstances. They should always represent an error which cannot be gracefully handled at the level the error occurred.
Calling exit() would not unwind the stack from wherever you called it. If you want to exit cleanly, what you're already doing is ideal.
You have already accepted an answer, but I wanted to add something about this:
Can I just explicitly call something like exit() instead?
You can call exit, but (probably) shouldn't.
std::exit should be reserved for situations where you want to express "exit right now!", not simply "application has nothing left to do".
As an example, if you were to write a controller for a laser used in cancer treatments, your first priority in case something went wrong would be to shut down the laser and call std::exit - or possibly std::terminate (to ensure any side effects of a hanging, slow or crashing application do not kill a patient).
Similar to how exceptions should not be used for controlling application flow, exit should not be used to stop the application in normal conditions.
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)?
Yes. This is the reason for using exceptions. An error occurred deep down in the code and something at a higher level will handle it. In your case, at the highest level.
There are arguments for/against exceptions vs. error codes, and this is a good read:
Exceptions or error codes
Can I just explicitly call something like exit() instead?
You can, but you may end up duplicating your logging code. Also, if in the future you decide that you want to handle an exception differently you will have to change all your exit calls. Imagine you wanted a different message, or to fall back on an alternative process.
Another similar question:
Correct usage of exit() in c++?
You also have a flaw in your approach as you don't handle all (C++) exceptions. You want something like this:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
catch (...)
{
// overload?
Notification::showErrorMessage("ERROR: Unhandled");
return 1;
}
return 0;
}
If you don't handle all* exceptions you could have the game terminate without telling you anything useful.
You can't handle ALL exceptions. See this link:
C++ catching all exceptions
From the documentation:
[[noreturn]] void exit (int status);
Terminate calling process
Terminates the process normally, performing the regular cleanup for terminating programs.
Normal program termination performs the following (in the same order):
Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
Objects with static storage duration are destroyed (C++) and functions registered with atexit are called.
All C streams (open with functions in ) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
Control is returned to the host environment.
Note that objects with automatic storage are not destroyed by calling exit (C++).
If status is zero or EXIT_SUCCESS, a successful termination status is returned to the host environment.
If status is EXIT_FAILURE, an unsuccessful termination status is returned to the host environment.
Otherwise, the status returned depends on the system and library implementation.
For a similar function that does not perform the cleanup described above, see quick_exit.
I have following code snippet:
try
{
if(/*something is true*/)
{
throw Win32Error(msgWin32Error->GetError()); //assume msgWin32Error is NULL
}
}
catch (Win32Error& win32Error)
{
}
Assuming msgWin32Error is NULL in above code snippet, when throw statement gets executed, it will have another exception in turn. What will be the behavior in such circumstance?
Thanks,
Su
There will be no C++ exception here.
You are conflating two things:
C++ exceptions (see: throw, try, catch)
Runtime errors invoked by the operating system (e.g. segmentation fault)
The latter are sometimes also confusingly called "exceptions", but you cannot catch these with C++ catch.
What will happen is that the dereference of msgWin32Error will (probably) cause the Operating System to terminate your application. Control will never even reach your throw instruction.
First of all, when you dereference a NULL pointer, you get undefined behavior. An exception might be thrown (because throwing an exception is in the list of allowable behaviors if UB is invoked), but you can't count on that. However, it's easy to construct a well defined example that gets at what I think you are asking.
char const* foo()
{
throw ExceptionZ();
return "message";
}
void bar()
{
try
{
throw ExceptionX(foo());
}
catch(ExceptionX) { ... }
catch(ExceptionZ) { ... }
}
In this case, the handler for ExceptionZ will be entered. The throw statement in bar does not complete. The exception thrown from foo() propagates before it can.
Can some please explain why this exception isn't caught.
try {
// This will cause an exception
char *p = 0;
char x = 0;
*p = x;
}
catch (...) {
int a = 0;
}
When I run the program it dies on the line *p = x. I would expect that the catch block would cause this exception to be ignored.
I'm using the Qt Creator (2.2) with Qt 4.7.2 compiling with Visual Studios 2008 on Windows 7 32 bit.
There is no C++ exception being thrown here. You are causing undefined behavior because *p = x derefences a pointer with a null pointer value.
An exception is only propogated when you, or code you call, executes a throw expression. Undefined behaviour is not usually catchable.
Structured exception handling __try and __catch will catch system faults, see:
http://msdn.microsoft.com/en-us/library/swezty51(v=vs.80).aspx
Dereferencing a NULL pointer is undefined behaviour. In general, this will trigger a processor trap, and an OS level error. This may then be mapped to a signal, such as SIGSEGV, or to an Access Violation error, or it may abort your program, or do anything else.
On Windows, it is mapped to a "structured exception", which is a different beast to a C++ exception. Depending on how you've got MSVC configured, you may be able to catch this with catch(...), but not always.
If you want that you need to write a pointer test:
template<typename T>
inline T* ptr_test(T* test)
{
if (test == NULL)
{ throw std::runtime_error("Null Exceception");
}
return test;
}
Then your code looks like this:
try
{
// This will cause an exception
char* p = 0;
char x = 0;
*ptr_test(p) = x; // This is what java does.
// Fortunately C++ assumes you are smart enough to use pointers correctly.
// Thus I do not need to pay for this test.
//
// But if you want to pay for the test please feel free.
}
catch (...)
{
int a = 0;
}
You need to use the /EHa compiler option to switch on the (Microsoft compiler specific) feature which will enable SEH (Structured Exception Handling) exceptions (which is what your null access triggers) to be catchable by catch(...).
Having said that, I wouldn't recommend using /EHa. Better to use the __try/__except extension or the SEH API directly and keep your handling of "structured" exceptions separate from handling of C++ exceptions. Why ? Because C++ exceptions are just another perfectly legitimate well defined control flow mechanism, but most things which trigger SEH exceptions are likely to indicate your software has entered the realm of undefined behaviour and really the only sensible thing to do is exit gracefully. Using /EHa leads to this vital difference becoming unnecessarily blurred.
It's not caught because its not an exception - nothing is throwing. You're accessing null/unallocated memory which causes a segmentation fault which is a signal from the operating system itself.
Signals can only be caught by signal handlers, exceptions will not help you with those.
Exceptions only really help in areas where something might call throw(), like a library throwing an exception when you cause a divide-by-zero with the parameters you provided it.
All you're doing right now is dereferencing a null pointer, it is not an exception.
If you want this code to catch something, you have to throw something first. Say, something like:
try {
// This will cause an exception
char *p = 0;
char x = 0;
if (p == 0) throw 1;
*p = x;
}
catch (...) {
int a = 0;
}
Obviously, the catch block in the above example will always be executed.
Does C++ offer a way to 'show' something visual if an unhandled exception occurs?
What I want to do is to make something like assert(unhandled exception.msg()) if it actually happens (like in the following sample):
#include <stdexcept>
void foo() {
throw std::runtime_error("Message!");
}
int main() {
foo();
}
I expect this kind of code not to terminate immediately (because exception was unhandled), rather show custom assertion message (Message! actually).
Is that possible?
There's no way specified by the standard to actually display the message of the uncaught exception. However, on many platforms, it is possible anyway. On Windows, you can use SetUnhandledExceptionFilter and pull out the C++ exception information. With g++ (appropriate versions of anyway), the terminate handler can access the uncaught exception with code like:
void terminate_handler()
{
try { throw; }
catch(const std::exception& e) { log(e.what()); }
catch(...) {}
}
and indeed g++'s default terminate handler does something similar to this. You can set the terminate handler with set_terminate.
IN short, no there's no generic C++ way, but there are ways depending on your platform.
Microsoft Visual C++ allows you to hook unhandled C++ exceptions like this. This is standard STL behaviour.
You set a handler via a call to set_terminate. It's recommended that your handler do not very much work, and then terminate the program, but I don't see why you could not signal something via an assert - though you don't have access to the exception that caused the problem.
I think you would benefit from a catch-all statement as follows:
int main() {
try {
foo();
catch (...) {
// Do something with the unhandled exception.
}
}
If you are using Windows, a good library for handling unhandled exceptions and crashes is CrashRpt. If you want to do it manually you can also use the following I wrote in this answer.
If I'm reading your question correctly, you're asking if you can overload throw (changing its default behavior) so it does something user-defined. No, you can't.
Edit: since you're insistent :), here's a bad idea™:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
void monkey() {
throw std::exception("poop!");
}
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
std::cout << "poop was thrown!" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
int main() {
SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
monkey();
return 1;
}
Again, this is a very bad idea, and it's obviously platform-dependent, but it works.
Yes, its possible. Here you go:
#include <iostream>
#include <exception>
void foo()
{
throw std::exception("Message!");
}
int main()
{
try
{
foo();
}
catch (std::exception& e)
{
std::cout << "Got exception: " << e.what() << std::endl;
}
return 0;
}
The c++ standard is the terminate handler - as other have said
If you are after better traceablility for throws then this is what we do
We have a macro Throw that logs the file name and line number and message and then throws. It takes a printf style varargs message.
Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);
I get a nice log message
Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99
If you're really interested in what happened to cause your program to fail, you might benefit from examining the process image in a post-mortem debugger. The precise technique varies a bit from OS to OS, but the basic train is to first enable core dumping, and compile your program with debug symbols on. Once the program crashes, the operating system will copy its memory to disk, and you can then examine the state of the program at the time it crashed.
I'm using the GLUTesselator and every once in a while EndContour() fails so I did this:
try
{
PolygonTesselator.End_Contour();
}
catch (int e)
{
renderShape = false;
return;
}
Why would it still crash, it should perform the catch code right?
How could I fix this?
Thanks
Does PolygonTesselator.End_Contour(); crash or throws it an exception?
Note that a real "crash" (segfault, illegal instruction etc.) does not throw an exception in the sense of C++.
In these cases, the CPU triggers an interrupt - this is also sometimes called exception, but has nothing to do with an C++ exception.
In C++ you are running on a real CPU - and not in a virtual machine like in Java where every memory violation results in language execption like NullPointerException or ArrayOutOfBoundsException.
In C/C++ a CPU exception / interrupt / trap is handled by the operating system and forwarded to the process as "signal". You can trap the signal but usually this does not help for crashes (SIGSEG, SIGILL, SIGFPU, etcc.).
You're getting SEH exception, or Structured Exception Handling. These exceptions are thrown by Windows under an entirely different system since SEH predates C++, and can't be caught by a standard C++ catch block (MSVC does however provide SEH catching).
Alternatively, if you're on Unix, the kernel doesn't use C++ exceptions either. It uses signals. I don't pretend to understand signals, since I don't develop for Unix, but I'm very sure they're not C++ exceptions.
You've violated a hardware rule that you can't de-reference a NULL pointer. You'll get an OS-level error, by exception or signal. You can't catch these things in a C++ catch block just like that.
Edit: If you're using MSVC on Windows and have a recent compiler, you CAN enable /EHa, which allows you to catch Structured Exceptions as well as C++ exceptions. I wrote this code that functions as shown:
int main() {
std::string string = "lolcakes";
try {
Something s;
int i, j;
i = 0; j = 1;
std::string input;
std::cin >> input;
if (input == "Structured")
int x = j / i;
else
throw std::runtime_error("Amagad hai!");
}
catch(std::runtime_error& error) {
std::cout << "Caught a C++ exception!" << std::endl;
}
catch(...) {
std::cout << "Caught a structured exception!" << std::endl;
}
return main();
}
Structured Exceptions include Access Violations, your particular error.
Two things :
If you are under VC 6 or more recent, use __try{}__except(EXCEPTION_EXECUTE_HANDLER){} instead. It will catch the SE. try/catch only catches C++ exceptions
I've had a hard time with GLU, so I can tell you this : if you can set the normal, SET IT. But otherwise, it's true that it's quite solid.
Since all you want to do when the exception arrives is set 'renderShape' to false I'd recomment the following code:
try
{
PolygonTesselator.End_Contour();
}
catch (...) // takes any type of exception
{
renderShape = false;
return;
}
That said of course if you really can't fix the source to the exception itself!!
Why would it still crash, it should
perform the catch code right? How
could I fix this?
Most likely because you are not actually catching what is being thrown. Are you sure that PolygonTesselator.End_Contour(); throws an int?
If your program fails with the message error reading from location 0x000000000, then it is not failing because of an exception, but because of a segfault. You can use the segvcatch utility to convert segfaults into catchable exceptions. Check out their examples.
As mentioned, this is an SEH Exception.
If you are using Visual Studio, you can configure your project to catch SEH exceptions in your try/catch block.
Project Properties > C/C++ > Code
Generation > Enable C++ Exceptions >
Yes with SEH Exceptions