This is the code:
#include <iostream>
void f() {
throw 1;
std::cout << "f(): should not be printed!!\n";
std::cout << "f(): not should this!!\n";
}
int main(int, const char**) {
f();
std::cout << "main(): This not be printed!!\n";
return 0;
}
When run as a console application, in debug mode and under the debugger there is no stack unwinding and the cout statements get printed?
This is technically possible if you run with the debugger. You didn't tell the whole story though. The debugger will display a dialog first when the exception is thrown. It looks similar to this (mine is VS2012 on Windows 8):
If you click the Break button then the debugger will break at the throw statement, giving you a chance to inspect state. When you click the Continue button then the exception is ignored and the program will continue as though nothing happened. This also happens when you break and then resume running.
This is a feature, not a bug, it allows you to rescue a debug session on which you already spent a lot of time. It is of course not often that useful to continue since your program is likely to be in a bad state but the alternative isn't great either. You almost always want to favor clicking Break and use the debugger to correct state so that you can meaningfully continue debugging.
Of course this will never happen without a debugger, your program will instantly terminate.
The only possible way that a stack unwind is ever going to happen is by writing a catch clause that catches the exception. Regardless of whether you are debugging or not.
The key in answering my own question lies in answering another sub-question: right after an exception is thrown, at which point does the stack unwinding begin? By stack unwinding is meant the call, in reverse order, of destructors of all automatic objects that still exist. Answer: at the point the control is passed to the exception handler, i.e. the exception is caught. If the exception is not caught, the C++ exception mechanism dictates that the terminate function is to be called and this in effect by default calls abort(). This mechanism can be seen in action by the following code:
struct X {
~X() { std::cout << "~X !!\n"; }
};
int main(int, const char**) {
X x;
throw 1;
return 0;
}
After the throw, the destructor for X is never called because the no exception handler has gained control and so the program aborts.
Back to the initial question, in the situation of when you are debugging a debug build and during execution of the program an exception is thrown when there is no suitable try-catch block around it, the MS Studio debugger breaks at the throw point and presents you with the dialogue window shown above and provides you with the option to “continue”. Continue is to be interpreted not as “carry on with the exception mechanism” but as “carry as if nothing has happened” i.e. with the next line of code after the throw.
Related
I have read many articles about SEH exceptions in StackOverflow and CodeProject.net.
After I implemented SEH exceptions handling in my C++ program, I was affected by stack overflow exception, which hadn't been caught by my software.
After next part of research I understand, that it's impossible to detect such exception programmatically, because we don't have free stack address space to use, so program memory is corrupted.
I would like to ask you about your experience in handling stack overflow exception. It looks like a challenge and I'm really interested if it's not possible in unmanaged code programming languages?
Below I present a part of my sample program (C++), which reproduces stack overflow exception. It works perfectly for any SEH exception, but not stack overflow:
LONG WINAPI SehHandler(PEXCEPTION_POINTERS pExceptionPtrs)
{
cerr << "Handled SEH exception!\n";
cerr << "ContextRecord: " << pExceptionPtrs->ContextRecord << endl;
cerr << "ExceptionRecord: " << pExceptionPtrs->ExceptionRecord << endl;
// Write minidump file
CreateMiniDump(pExceptionPtrs);
// Terminate process
TerminateProcess(GetCurrentProcess(), 1);
return EXCEPTION_EXECUTE_HANDLER;
}
int fib(unsigned int n) {
if(n == 0) return 0;
if(n == 1) return 1;
return fib(n-1)+fib(n-2);
}
int main(){
SetUnhandledExceptionFilter(SehHandler);
cout << fib(1000000);
return 0;
}
Yes, you can get a minidump out of a SO crash, but never the way you are doing it now. Your SehHandler() function runs on the thread that triggered the exception. And it is in a perilous state, you have about ~7080 bytes of emergency stack space left to do what you need to do. If you consume that then the program will fail with an uncatchable access violation exception.
You cannot call MiniDumpWriteDump() and hope to survive it, that function requires more stack than you have available. So it is a hard kaboom without a minidump.
You need another thread to make that call. That could be, for example, a thread that you create at initialization and block with a WaitForMultipleObjects() call. Your SehHandler() can call SetEvent() to wake it up. After writing the PEXCEPTION_POINTERS value to a global variable. And block indefinitely to allow the thread to create the minidump and abort the process.
Fwiw, by far the best place for that thread is in another process. That also allows you to deal with the really nasty ones that completely corrupt the process state. A "guard" process that you start at initialization. With a named event to signal it and, say, a memory-mapped file to pass the PEXCEPTION_POINTERS. Don't start it in SehHandler(), the process heap is no longer reliable so CreateProcess() cannot work anymore, you have to do it early.
The answer from Hans Passant indicates that there's 7080 bytes of emergency stack. I don't know where that info comes from, and he hasn't answered #nop above, and my findings indicate that that info is incorrect. However this site won't allow me to comment above for some reason, so I'll just leave this here...
There's a function that can be used to query and set how much emergency stack is left to the stack handler: SetThreadStackGuarantee(). Note that since Windows 10 definitely (but I think it's since Windows 7 as well), in most cases this value will be 0. So there's no way to do anything complicated in the handler, by default. You may be able to signal another thread or an external process, as Hans has suggested, but that's all.
However, if you don't want to implement such a complicated solution, and can spare some slack space on the stack, it is easiest to use SetThreadStackGuarantee() to set this to a value high enough that you can continue handling the stack overflow exception just like any other. Note that you need to call this function on each thread that needs this feature, and call it before the stack overflow occurs, so preferably at thread initialization.
I have GDB attached to a process that is currently inside a catch(...) block.
Is there a known technique to access that thrown exception?
The program in question is a gcc/x86-64 binary, but I'm also curious about other builds.
As you say, you can re-throw it, so you can re-throw it inside another try/catch block with more specific clauses to extract the exception (and another ... if you want as well). You can even do this inside another function so you can centralize your exception handling.
Edit: I misunderstood the importance of gdb in your question, but you can apply the idea I described. Make a function that re-throws the exception you can set a breakpoint in:
void
helper()
{
try {
throw;
} catch (int i) {
// anything that won't get optimized away
volatile int j = i; // breakpoint here
}
}
Then in gdb just do call helper(). I just tested this to be sure it worked.
Further edit: If you literally mean I'm running a program under gdb right now and you are not exiting gdb until you are sure you can't get the exception, then it's time to look at eh_throw.cc and friends in the gcc source. __cxa_rethrow starts with:
__cxa_eh_globals *globals = __cxa_get_globals ();
__cxa_exception *header = globals->caughtExceptions;
You will have to examine all of those structures to figure out what's buried inside.
I have not tested this - but the exception (or at least a pointer to it) should probably be on the stack somewhere close to the head. I guess the exact position and format is implementation dependent, but you should be able casting different addresses in this area of the stack to your exception type (or at least to std::exception) and see if you get meaningful results.
Out of my curiosity..
I notice when I throw exceptions from constructor, if I compiled the code in debug mode and if I click on continue debugging (or continue stepping through), it won't exit the constructor until it reaches the end. Please note I don't have try{}catch{} wrapping the code that instantiate MyClass object.
I tried this in release mode, and can't really tell if it exits the constructor after the first throw or the last throw. Do you know if in release mode it leaves ctor since the first throw or the last? And why does it let me go to the next line when I'm in debug? shouldn't throw just exit the scope it's in?
MyClass::MyClass()
{
throw "exception1";
throw "exception2";
throw "exception3";
}
MyClass a;
I suspect that it's a debugging issue. An uncaught exception should, by default, kill the program. But your debugger stops the program at the line that caused the exception, instead. And the "continue debugging" button tells the debugger to just ignore the last fatal problem and continue going.
So the debugger continues on in the program until it reaches the second throw. Which would, again, be fatal. So the debugger stops there. Etc.
If there's a place that actually catches the thrown exception, you should see different behavior.
I would like my C++ code to stop running if a certain condition is met, but I'm not sure how to do that. So just at any point if an if statement is true terminate the code like this:
if (x==1)
{
kill code;
}
There are several ways, but first you need to understand why object cleanup is important, and hence the reason std::exit is marginalized among C++ programmers.
RAII and Stack Unwinding
C++ makes use of a idiom called RAII, which in simple terms means objects should perform initialization in the constructor and cleanup in the destructor. For instance the std::ofstream class [may] open the file during the constructor, then the user performs output operations on it, and finally at the end of its life cycle, usually determined by its scope, the destructor is called that essentially closes the file and flushes any written content into the disk.
What happens if you don't get to the destructor to flush and close the file? Who knows! But possibly it won't write all the data it was supposed to write into the file.
For instance consider this code
#include <fstream>
#include <exception>
#include <memory>
void inner_mad()
{
throw std::exception();
}
void mad()
{
auto ptr = std::make_unique<int>();
inner_mad();
}
int main()
{
std::ofstream os("file.txt");
os << "Content!!!";
int possibility = /* either 1, 2, 3 or 4 */;
if(possibility == 1)
return 0;
else if(possibility == 2)
throw std::exception();
else if(possibility == 3)
mad();
else if(possibility == 4)
exit(0);
}
What happens in each possibility is:
Possibility 1: Return essentially leaves the current function scope, so it knows about the end of the life cycle of os thus calling its destructor and doing proper cleanup by closing and flushing the file to disk.
Possibility 2: Throwing a exception also takes care of the life cycle of the objects in the current scope, thus doing proper cleanup...
Possibility 3: Here stack unwinding enters in action! Even though the exception is thrown at inner_mad, the unwinder will go though the stack of mad and main to perform proper cleanup, all the objects are going to be destructed properly, including ptr and os.
Possibility 4: Well, here? exit is a C function and it's not aware nor compatible with the C++ idioms. It does not perform cleanup on your objects, including os in the very same scope. So your file won't be closed properly and for this reason the content might never get written into it!
Other Possibilities: It'll just leave main scope, by performing a implicit return 0 and thus having the same effect as possibility 1, i.e. proper cleanup.
But don't be so certain about what I just told you (mainly possibilities 2 and 3); continue reading and we'll find out how to perform a proper exception based cleanup.
Possible Ways To End
Return from main!
You should do this whenever possible; always prefer to return from your program by returning a proper exit status from main.
The caller of your program, and possibly the operating system, might want to know whether what your program was supposed to do was done successfully or not. For this same reason you should return either zero or EXIT_SUCCESS to signal that the program successfully terminated and EXIT_FAILURE to signal the program terminated unsuccessfully, any other form of return value is implementation-defined (§18.5/8).
However you may be very deep in the call stack, and returning all of it may be painful...
[Do not] throw an exception
Throwing an exception will perform proper object cleanup using stack unwinding, by calling the destructor of every object in any previous scope.
But here's the catch! It's implementation-defined whether stack unwinding is performed when a thrown exception is not handled (by the catch(...) clause) or even if you have a noexcept function in the middle of the call stack. This is stated in §15.5.1 [except.terminate]:
In some situations exception handling must be abandoned for less subtle error handling techniques. [Note: These situations are:
[...]
— when the exception handling mechanism cannot find a handler for a thrown exception (15.3), or when the search for a handler (15.3) encounters the outermost block of a function with a noexcept-specification that does not allow the exception (15.4), or [...]
[...]
In such cases, std::terminate() is called (18.8.3). In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called [...]
So we have to catch it!
Do throw an exception and catch it at main!
Since uncaught exceptions may not perform stack unwinding (and consequently won't perform proper cleanup), we should catch the exception in main and then return a exit status (EXIT_SUCCESS or EXIT_FAILURE).
So a possibly good setup would be:
int main()
{
/* ... */
try
{
// Insert code that will return by throwing a exception.
}
catch(const std::exception&) // Consider using a custom exception type for intentional
{ // throws. A good idea might be a `return_exception`.
return EXIT_FAILURE;
}
/* ... */
}
[Do not] std::exit
This does not perform any sort of stack unwinding, and no alive object on the stack will call its respective destructor to perform cleanup.
This is enforced in §3.6.1/4 [basic.start.init]:
Terminating the program without leaving the current block (e.g., by calling the function std::exit(int) (18.5)) does not destroy any objects with automatic storage duration (12.4). If std::exit is called to end a program during the destruction of an object with static or thread storage duration, the program has undefined behavior.
Think about it now, why would you do such a thing? How many objects have you painfully damaged?
Other [as bad] alternatives
There are other ways to terminate a program (other than crashing), but they aren't recommended. Just for the sake of clarification they are going to be presented here. Notice how normal program termination does not mean stack unwinding but an okay state for the operating system.
std::_Exit causes a normal program termination, and that's it.
std::quick_exit causes a normal program termination and calls std::at_quick_exit handlers, no other cleanup is performed.
std::exit causes a normal program termination and then calls std::atexit handlers. Other sorts of cleanups are performed such as calling static objects destructors.
std::abort causes an abnormal program termination, no cleanup is performed. This should be called if the program terminated in a really, really unexpected way. It'll do nothing but signal the OS about the abnormal termination. Some systems perform a core dump in this case.
std::terminate calls the std::terminate_handler which calls std::abort by default.
As Martin York mentioned, exit doesn't perform necessary clean-up like return does.
It's always better to use return in the place of exit.
In case if you are not in main, wherever you would like to exit the program, return to main first.
Consider the below example.
With the following program, a file will be created with the content mentioned.
But if return is commented & uncommented exit(0), the compiler doesn't assure you that the file will have the required text.
int main()
{
ofstream os("out.txt");
os << "Hello, Can you see me!\n";
return(0);
//exit(0);
}
Not just this, Having multiple exit points in a program will make debugging harder.
Use exit only when it can be justified.
Call the std::exit function.
People are saying "call exit(return code)," but this is bad form. In small programs it is fine, but there are a number of issues with this:
You will end up having multiple exit points from the program
It makes code more convoluted (like using goto)
It cannot release memory allocated at runtime
Really, the only time you should exit the problem is with this line in main.cpp:
return 0;
If you are using exit() to handle errors, you should learn about exceptions (and nesting exceptions), as a much more elegant and safe method.
return 0; put that wherever you want within int main() and the program will immediately close.
The program will terminate when the execution flow reaches the end of the main function.
To terminate it before then, you can use the exit(int status) function, where status is a value returned to whatever started the program. 0 normally indicates a non-error state
Either return a value from your main or use the exit function. Both take an int. It doesn't really matter what value you return unless you have an external process watching for the return value.
If you have an error somewhere deep in the code, then either throw an exception or set the error code. It's always better to throw an exception instead of setting error codes.
Generally you would use the exit() method with an appropriate exit status.
Zero would mean a successful run. A non-zero status indicates some sort of problem has occurred. This exit code is used by parent processes (e.g. shell scripts) to determine if a process has run successfully.
Beyond calling exit(error_code) - which calls atexit handlers, but not RAII destructors, etc.
- more and more I am using exceptions.
More and more my main program looks like
int main(int argc, char** argv)
{
try {
exit( secondary_main(argc, argv );
}
catch(...) {
// optionally, print something like "unexpected or unknown exception caught by main"
exit(1);
}
}
where secondary_main
in where all the stuff that was originally is put --
i.e. the original main is renamed secondary_main, and the stub main above is added.
This is just a nicety, so that there isn't too much code between the tray and catch in main.
If you want, catch other exception types.
I quite like catching string error types, like std::string or char*, and printing those
in the catch handler in main.
Using exceptions like this at least allows RAII destructors to be called, so that they can do cleanup. Which can be pleasant and useful.
Overall, C error handling - exit and signals - and C++ error handling - try/catch/throw exceptions - play together inconsistently at best.
Then, where you detect an error
throw "error message"
or some more specific exception type.
If the condition I'm testing for is really bad news, I do this:
*(int*) NULL= 0;
This gives me a nice coredump from where I can examine the situation.
Dude... exit() function is defined under stdlib.h
So you need to add a preprocessor.
Put include stdlib.h in the header section
Then use exit(); wherever you like but remember to put an interger number in the parenthesis of exit.
for example:
exit(0);
If your if statement is in Loop You can use
break;
If you want to escape some code & continue to loop Use :
continue;
If your if statement not in Loop You can use :
return 0;
Or
exit();
To break a condition use the return(0);
So, in your case it would be:
if(x==1)
{
return 0;
}
I found some code in a project which looks like that :
int main(int argc, char *argv[])
{
// some stuff
try {
theApp.Run();
} catch (std::exception& exc) {
cerr << exc.what() << std::endl;
exit(EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}
I don't understand why the exceptions are being catched. If they weren't, the application would simply exit and the exception would be printed.
Do you see any good reason to catch exceptions here ?
EDIT : I agree that it is good to print the exception error. However, wouldn't it be better to rethrow the exception ? I have the feeling that we are swallowing it here...
If an exception is uncaught, then the standard does not define whether the stack is unwound. So on some platforms destructors will be called, and on others the program will terminate immediately. Catching at the top level ensures that destructors are always called.
So, if you aren't running under the debugger, it's probably wise to catch everything: (...) as well as std::exception. Then your application code can clean up with RAII even on a fatal exception. In many such cases you don't actually need to clean up, since the OS will do it for you. But for instance you might prefer to disconnect cleanly from remote services where possible, and there might be resources external to the process, such as named pipes/mutexes, that you'd prefer to destroy rather than leaking.
Rethrowing the exception in main seems to me of limited use, since you've already lost the context in which it was originally thrown. I suppose that trapping an uncaught exception in the debugger is noisier than just logging the fault to std::cerr, so rethrowing would be the smart move if there's a chance of missing the logging.
If you want the debugger to trap unexpected conditions in debug mode, which in release mode throw an exception that eventually results in an exit, then there are other ways to do that than leaving the exception uncaught so that the debugger sees it. For example, you could use assert macros. Of course, that doesn't help with unexpected and unpredictable conditions, like hardware exceptions if you're using SEH on .NET.
Why do you say that the exception would be printed? This is not the typical behavior of the C++ runtime. At best, you can expect that its type gets printed.
In addition, this program leaves a "failure" status, whereas an exception might cause a termination-through-abort status (i.e. with a signal indicated in the exit code).
Try-catch in the main function hides the exception from debugger. I would say, it isn't good.
On the other hand, customers are not expected to have debuggers, so catching exceptions is nice. So it is good.
Personally, I catch all exceptions in main function, when making a release build, and I don't do that, when building a debug configuration.
A simple example of a situation where the stack did not unwind:
Why destructor is not called on exception?
A list of situations where exceptions may cause the application to terminate rather than unwind the stack.
Why destructor is not called on exception?
If an exception is not caught at any level and would escape main() then the implementation is allowed to call terminate() rather that unwinding the stack (yes this caught me by surprise as well).
As a result I always catch all exceptions in main().
int main()
{
try
{
}
catch(std::exception const& e)
{ /* LOG */
// optimally rethrow
}
catch(...) // Catch anything else.
{ /* LOG */
// optimally rethrow
}
}
To help with catching problems during debugging. Derive your exceptions from std::exception and then stick the break point in the constructor for std::exception.
This is a global catch block. It is common for displaying a nice and user understood message ('Internal error') instead of a cryptic exception print-out. This may be not evident from the specific code block, but it is in general a good idea.
Have a look at the C++ bible i.e. Stroustrup, he has an example which is also repeated in Applied C++ programming. The reasoning is:
int main(void)
{
try
{
// your code
}
catch ( /* YourPossibleExceptions i.e. barfs you expect may occur */ )
{
}
catch ( ... ) // unexpected errors, so you can exit gracefully
{
}
}
According the the Windows spec, the main isn't allowed to throw.
(practically it results into the message that asks if you want to send the bug-report to Microsoft)