I get this terminating with uncaught exception even though I thought I had caught the exception. Here is some example code
#include <iostream>
#include <stdexcept>
void throwing(int x)
{
if(x) throw std::runtime_error("x non-null");
}
int main()
{
try {
throwing(1);
} catch(std::runtime_error const&ex) {
std::clog << "error: \"" << ex.what() << '\"' << std::endl;
std::terminate();
}
return 0;
}
which produces (after reporting error: "x non-null") the said message (using clang++ with std=c++11). So, when exactly has the exception been caught and hence deemed uncaught in the sense of terminate() not reporting it (again)? Or, equivalently (or not?): how can I catch an exception, report its what(), and terminate() without getting this blurb?
(I could refrain from reporting the what() and just terminate(), but I want to report the what() in my own way.)
Since noone provided an answer to this, and it seems like my comment was either not clear enough or overlooked, I'll post a full answer:
Or, equivalently (or not?): how can I catch an exception, report its what(), and terminate() without getting this blurb?
If you read carefully thru the reference, you'll notice std::terminate() by default calls abort(), which causes the program to terminate returning a platform-dependent unsuccessful termination error code to the host environment.
Now, answering the quoted question: either use exit(int status) (which is a better solution, since you handled the exception) instead of terminate, or change the terminate handler.
Related
I wanted to know what header is required to catch std::unexpected exception. I am currently doing something like this. I would like the breakpoint of std::unexpected catcher to be hit. I am using VS2012
#include <iostream>
#include <exception>
void myfunction () throw (int)
{
throw "ABC";
}
int main()
{
try
{
myfunction();
}
catch(std::exception &f)
{
//breakpoint
}
catch( std::unexpected &f)
{
//breakpoint
}
}
When i try to build this code I get the error
"Error 2 error C2061: syntax error : identifier 'unexpected'
Am i missing a header ?
Update :
I realize now that std::unexpected is a function. So from what I understand is that if myfunction throws anything other than an int then std::unexpected method is called which defaults to terminate. So my question now becomes if I add the exception handler catch( ...) to the above code the breakpoint in catch( ...) is called. Which exception is that ? Does this catch std::unexpected exceptions ?
std::unexpected is called (yes, it is a function) when a function throws an exception whose type isn't listed in the dynamic exception specification. What you could do is use std::set_unexpected to register a handler that will be called.
#include <iostream>
#include <exception>
void myfunction () throw (int)
{
throw "Lol";
}
int main ()
{
std::set_unexpected ([] {std::cerr << "Unexpected stuff!"; throw 0; });
try
{
myfunction();
}
catch (int) { std::cerr << "caught int\n"; }
catch (...) { std::cerr << "caught some other exception type\n"; }
}
Note that both dynamic exception specifications and std::unexpected/std::set_unexpected became deprecated with C++11.
Updated part:
So my question now becomes if I add the exception handler catch(...)
to the above code the breakpoint in catch(...) is called.
That depends on where you put that handler. Putting it into main wont help - std::terminate will still get called. Putting it into myfunction would work but make the exception specification pointless.
Which exception is that ? Does this catch std::unexpected exceptions ?
catch(...) doesn't do magic. It simply matches every exception type, just as a variadic function (with an ellipse in the parameter-clause) can take every argument type*. It isn't different from the other handlers at all when it comes to unexpected exceptions.
* The slight difference is that catch(...) can catch non-POD-types without invoking undefined behavior.
Loopunroller's answer is correct as far as the C++ standard is concerned, but Visual C++'s implementation of dynamic exception specifications is utterly nonconforming - that is, it does not behave in the way specified in the C++ standard at all.
As explained in their documentation, dynamic exception specifications behaves like this in Visual C++:
no specification or throw (...): function can throw anything
throw (<nonempty-list-of-types>): function can throw anything, including things not in the list
throw (): function can't throw.
Microsoft's compiler generates code for a throw() function on the assumption that it doesn't throw. If it ends up throwing, std::unexpected() is not called, the program will simply behave incorrectly.
This is why your catch(...) in main() ended up catching the exception thrown from myfunction (and why unexpected() isn't called). Basically, in Microsoft's world, the throw (int) specification you attached to myfunction is about as meaningful as whitespace.
I am calling a function and I am throwing an exception in that function. But I don't want to catch that in the same function but want to catch it where that function was called, like here is my example code.
void foo()throw(...){
std::cout << "FOO" <<std::endl;
throw "Found";
}
void main(){
try{
foo();
}
catch(...){
std::cout << "exception catched" <<std::endl;
}
}
But it is crashing at the point where I am throwing the exception in foo function, but I want to catch it in the main function.
How would I do that?
throw;
throw with no operand rethrows the exception that is currently being handled. That means it can only be used in a catch block. Since you aren't in a catch block when the throw; is executed, the program is terminated.
You need to throw something, like a runtime error: throw std::runtime_error("oops");.
Note also that exception specifications (e.g. the throw(...) in void foo() throw(...)) should not be used. For an explanation as to why, see "A Pragmatic Look at Exception Specifications."
Got answer my own question at http://msdn.microsoft.com/en-US/library/wfa0edys%28v=VS.80%29.aspx
Can an ellipsis try-catch be used to catch all the errors that can lead to a crash? Are there are any anomalies?
try
{
//some operation
}
catch(...)
{
}
No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.
You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).
If the code inside try/catch block crashed somehow, the program is anyway in a non-recoverable state. You shouldn't try to prevent the crash, the best that the program can do is just let the process crash.
The "anomaly" is in the fact that your code only catches the exceptions, and not the errors. Even if the code is exception-safe (which may be not the case, if you are trying to work-around its mistakes by a try/catch block), any other inner error may bring the program into irrecoverable state. There is simply no way to protect the program from it.
Addition: look at this article at "The Old New Thing" for some insights.
It is the Catch All handler.
It catches all the C++ exceptions thrown from the try block. It does not catch segfault and other signals that cause your program to crash.
While using it, You need to place this handler at the end of all other specific catch handlers or it all your exceptions will end up being caught by this handler.
It is a bad idea to use catch all handler because it just masks your problems and hides the programs inability by catching all(even unrecognized) exceptions. If you face such a situation you better let the program crash, and create a crash dump you can analyze later and resolve the root of the problem.
It catches everything that is thrown, it is not limited to exceptions. It doesn't handle things like windows debug asserts, system signals, segfaults.
TEST(throw_int) {
try {
throw -1;
} catch (std::exception &e) {
std::cerr << "caught " << e.what() << std::endl;
} catch (...) {
std::cerr << "caught ..." << std::endl;
}
}
Throwing an integer isn't really recommended though. It's better to throw something that inherits from std::exception.
You might expect to see something like this as a last ditch effort for documenting failure, though. Some applications aren't required to be very robust. Internal tools might cost more than they are worth if you went through the paces of making them better than hacked together crap.
int main(int argc, char ** argv) {
try {
// ...
} catch (std::exception &e) {
std::cerr << "error occured: " << e.what() << std::endl;
return 1;
}
return 0;
}
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 was debugging an application and encountered following code:
int Func()
{
try
{
CSingleLock aLock(&m_CriticalSection, TRUE);
{
//user code
}
}
catch(...)
{
//exception handling
}
return -1;
}
m_CriticalSection is CCricialSection.
I found that user code throws an exception such that m_CriticalSection is not released at all. That means due to some reasons stack is corrupted and hence unwinding failed.
My question is:
1) In what different scenarios stack unwinding can fail ?
2) what different possibility of exception can be thrown such that stack unwinding fails.
3) Can I solve this problem by putting CSingleLock outside of try block ?
Thanks,
Are you getting an abnormal program termination?
I believe your CCriticalSection object will be released CSingleLock's destructor. The destructor will get called always since this is an object on the stack. When the usercode throws, all stacks between the throw and the catch in your function will be unwound.
However, chances are that some other object in your user code or even the CSingleLock destructor has thrown another exception in the meantime. In this case the m_CriticalSection object will not get released properly and std::terminate is called and your program dies.
Here's some sample to demonstrate. Note: I am using a std::terminate handler function to notify me of the state. You can also use the std::uncaught_exception to see if there are any uncaught exceptions. There is a nice discussion and sample code on this here.
struct S {
S() { std::cout << __FUNCTION__ << std::endl; }
~S() { throw __FUNCTION__; std::cout << __FUNCTION__ << std::endl; }
};
void func() {
try {
S s;
{
throw 42;
}
} catch(int e) {
std::cout << "Exception: " << e << std::endl;
}
}
void rip() {
std::cout << " help me, O mighty Lord!\n"; // pray
}
int main() {
std::set_terminate(rip);
try {
func();
}
catch(char *se) {
std::cout << "Exception: " << se << std::endl;
}
}
Read this FAQ for clarity.
Can I solve this problem by putting CSingleLock outside of try block ?
Hard to say without having a look at the stack and error(s)/crashes. Why don't you give it a try. It may also introduce a subtle bug by hiding the real problem.
Let me start by saying that I don't know what CSingleLock and CCriticalSection do.
What I do know is that an exception thrown in your "user code" section should unwind the stack and destroy any variables that were created within the try { } block.
To my eyes, I would expect your aLock variable to be destroyed by an exception, but not m_CriticalSection. You are passing a pointer to m_CriticalSection to the aLock variable, but the m_CriticalSection object already exists, and was created elsewhere.
are you sure that lifetime of your m_CriticalSection is longer that CSingleLock?
maybe someone corrupt your stack?
3) Can I solve this problem by putting CSingleLock outside of try block ?
in this case - yes. But remember, it is not good thing for performance to put large block in mutex.
btw, catch(...) is not good practice in general. in Win32 it (catch(...)) catching SEH exceptions too, not only c++ exception. maybe you have core in this function and catch it with catch(...).
My question is:
1) In what different scenarios stack unwinding can fail ?
If exit() terminate() abort() or unexpected() are called.
With the exception of a direct calls what situations are any of these likely to happen:
An unhandeled exception is thrown. (Does not apply here)
throw an exception from a destructor while another exception is popogating
2) what different possibility of exception can be thrown such that stack unwinding fails.
Exception thrown from constructor of throw expression
Exception thrown from destructor while exception propogating.
Exception thrown that is never caught (implementatin defined if this actually unwinds stack).
Exception thrown that is not specified in exception specification.
Exception thrown across a C ABI.
Exception thrown inside a thread that is not caught (Implementation defined what happens)
3) Can I solve this problem by putting CSingleLock outside of try block ?
No. All of the above cause the application to terminate without further unwinding of the stack.