How to catch exception without throw - c++

There is a CRASH in Function() due to some exceptions so, throw X would not be called. In this case how to call catch block to handle exceptions?
NOTE: we can't modify the code in Function() definition
Sample code:
cout << "Before try \n";
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}
catch (...) {
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
So can anyone help me out for this?

A "CRASH" is not an exception. It is Undefined Behaviour. Absolutely anything could have happened. You are lucky that the system detected it. It could have formatted your disk or summoned daemons out of your nose. Instead the system is only shutting down the process to prevent further damage.
The system might even be so kind as to let you define what to do instead of shutting down the process. The way to define it is system specific. In Unix, you need to install signal handler (the advanced way), in Windows you use structural exceptions.
But the problem is that if the function crashed, there is no way to tell how big mess it left the memory of the process in. You really have to fix the crash. A crash is always a bug.
The fact that a crash is inside that function does not automatically mean the bug is in that function. Most crashes I've seen happened in standard library functions, but they were not bugs in standard library. They were caused by incorrect use of those functions, or sometimes incorrect use of something different much earlier in the program. Because when you invoke Undefined Behaviour, there's no telling when it will cause a crash. Especially buffer overruns and writes to uninitialized pointers tend to cause crashes eventually when some unrelated code wants to use the variable that was overwritten.
That said if the bug is indeed in that function and you can't modify it, you will have to get somebody who can or find an alternative that works better. Because there's no way the program is going to work correctly otherwise.

There's an aditional '}' in the try block in your code. Not sure whether that was an error in typing the code or from another higher level block.
The catch(...){} block will be executed when any unhandled exception is thrown inside the try {} block. It doesn't matter whether the exceptions are thrown directly under the block or somewhere deep down in other function calls in the block.
cout << "Before try \n";
try
{
abc->Function1(); //A potential for crash
abc->Function2(); //Another potential for crash
abc->Function3(); //Another potential for crash
// Do some checks and throw an exception.
throw x;
cout << "After throw (Never executed) \n";
}
catch (...)
{
// This will catch all unhandled exceptions
// within the try{} block. Those can be from
// abc->Function1(), abc->Function2(), abc->Function3(),
// or the throw x within the block itself.
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
Hope that is helpful.

Here us the meaning of try and catch
try {
//[if some ABC type exception occur inside this block,]
}catch (ABC) {
//[Then, Do the things inside this block.]
}
So
after the exception occur in your abc->Function(); flow will directly jump in to catch block so write there what you need to do. as example.
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}catch (Exception ex) {
cout << "Exception Caught \n";
throw ex;
}
actually throw x; doesn't have any use here. because if your abc->Function(); worked fine, then it will throw an exception. so just remove that line.

the code you have written works exactly true . the compiler when see the throw command every where in the try{} it will go to the catch(){} so the cout << "After throw (Never executed) \n"; won't execute and then the code after the catch(){} will execute
for reading more about this case here is the link trycatch

If you got exception ,
abc->Function(); //Here is CRASH
You will enter in catch(...) block.
If you are using Windows OS, for OS generated exceptions you also need to use __try/__catch

Related

What does throw do when not in used with try and catch?

What does throw do when not used with try and catch? Like:
if (IsEmpty()) throw "Stack is empty, Cannot delete";
Does it get printed in console?
But when throw contains some int or char as its arguments, it is thrown to catch; what happens in this case?
The C++ runtime will have something along the lines of (this is NOT exactly how it looks, but you can think of it as working this way, unless you are working on something very special):
void BeforeMain()
{
try
{
int res = main();
exit(res);
}
catch(...)
{
cout << "Unhandled exception. Terminating..." << endl;
terminate();
}
}
You are allowed to do that, and it will not be caught anywhere within your code if you have not put an explicit try catch block.
Windows uses a SEH mechanism to handle , where you could have an uncaught exception filter to figure out about the same
See this post for more details
Catching exceptions thrown without try/catch

C++ try / catch (new to programming and not much info about this clause)

I am new to programming and am having trouble with try / catch clauses.
Here is an example from a textbook that I have:
int main( )
{
char *ptr;
try {
ptr = new char[ 1000000000 ];
}
catch( … ) {
cout << "Too many elements" << endl;
}
return 0;
}
I have tried to look online for a further explanation and the textbook does not exactly tell me what what these clauses actually do or what it is used for.
Any information would be helpful.
EDIT: The textbook I am using is:
C++: Classes and Data Structures by Jeffrey Childs
A try-catch is the C++ construct for exception handling. Google 'C++ exceptions'.
Try catch is a way of handling exceptions:
try
{
// Do work in here
// If any exceptions are generated then the code in here is stopped.
// and a jump is made to the catch block.
// to see if the exception can be handled.
// An exception is generated when somebody uses throw.
// Either you or one of the functions you call.
// In your case new can throw std::bad_alloc
// Which is derived from std::runtime_error which is derived from std::exception
}
// CATCH BLOCK HERE.
The catch block is where you define what exceptions you want to handle.
// CATCH BLOCK
catch(MyException const& e)
{
// Correct a MyException
}
catch(std::exception const& e)
{
// Correct a std::exception
// For example this would cat any exception derived from std::exception
}
You can have as many catch blocks as you like. If you exception matches any of the catch expressions in the catch statement then the associated block of code is executed. If no catch expressions matches an exception then the stack is unwound until it finds a higher level catch block and the processes is repeated (this can cause the application to exit if no matching catch block is found).
Note: If multiple catch expressions match then the lexically first one is used. Only one or none of the catch blocks will be executed. If none then the compiler will look for a higher level try/catch.
There is also a catch anything clause
catch(...)
{
// This is a catch all.
// If the exception is not listed above this will catch any exception.
}
So how does this apply to your code.
int main( )
{
char *ptr;
try
{
// This calls ::new() which can potentially throw std::bad_alloc
// If this happens then it will look for a catch block.
ptr = new char[ 1000000000 ];
// If the ::new() works then nothing happens and you pointer `ptr`
// is valid and code continues to execute.
}
catch( … )
{
// You only have one catch block that catches everything.
// So if there are any statements that generate an exception this will catch
// the excetption and execute this code.
cout << "Too many elements" << endl;
}
// As you have caught all exceptions the code will continue from here.
// Either after the try block finishes successfully or
// After an exception has been handled by the catch block.
return 0;
}
Try-catch blocks are used to trap errors in the code.
At the most basic level, errors occur because the program tries to execute an invalid instruction. That instruction (read: line of code) could be invalid for a number of reasons. In your specific instance, the instruction could be invalid if your program was not able to allocate 1,000,000,000 bytes of memory to story your ptr. The most common exception is trying to access a bad pointer, which is called a Null Pointer Exception, which occurs when you try to perform some action on an Object that either has not been created, or has been deleted (or got corrupt). You will learn to hate that exception.
Using catch(...) tells the program to execute the code inside the catch block if any error occurs inside the code within the try block. There you can handle your error and try to find someway to either fix the error condition or gracefully exit that module.
You can also catch specific errors, which you can find out more about here : http://www.cplusplus.com/doc/tutorial/exceptions/
If you already know C, try/catch achieves the same thing as setjmp/longjmp when used for error handling. Think of try as code for the if condition of setjmp and catch code for else of setjmp. This makes longjmp equivalent to throw in C++, which is used to throw an exception. In your example, probably, the new operator, which calls some memory allocation function internally, throws an exception on seeing a very large number as input by using the C++ throw operator.
void a()
{
.......
longjmp(buf,1); // <--- similar to throw
.......
}
if ( !setjmp(buf) ) // <--- similar to try
{
.......
a();
.......
}
else // <--- similar to catch
{
.......
}
try/catch is a bit more sophisticated than setjmp/longjmp, as for setjmp/longjmp you will need to declare variables which are modified in between setjmp/longjmp calls as volatile, which is not necessary for try/catch.

ellipsis try catch on c++

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;
}

How to handle a file destructor throwing an exception?

It's important to detect an error when you close a file to which you were writing, because the last part of your data could be flushed during the close, and if it's lost then your last write effectively failed and someone should know about it. The destructor for a file object is a nice place to automatically close it, but people say not to throw exceptions from destructors, so if the close fails then how do you know about it?
I've heard people recommend calling the close() method of the file manually. That's sounds nice, except what happens if the close() methods of multiple files all fail in a situation like this:
MyFile x(0), y(1), z(2);
x.close();
y.close();
z.close();
?
Well, it seems that if the close() method of 'x' throws an exception then you've done well to uphold the rule to avoid throwing exceptions in the destructor of 'x', except now you're good-intentioned early calls to the close() methods of 'y' and 'z' won't execute until their destructors. So, then when the close() method of 'y' is called in the destructor of 'y' or the close() method of 'z' is called in the destructor of 'z', and if they do throw exceptions then you're screwed.
Is there a reasonable way to not be screwed in such a situation?
Yes, catch the exception thrown from close in the destructor.
It is vitally important that a C++ destructor not throw an exception period. To do otherwise will mess up many of the resource management routines within virtually every available library.
True, you lose the failure information in this case by catching the exception. If the user is actually concerned about the error, they can manually call close and deal with the exception.
This is a FAQ item: 17.3 How can I handle a destructor that fails?
Edit:
Well, it seems that if the close()
method of 'x' throws an exception then
you've done well to uphold the rule to
avoid throwing exceptions in the
destructor of 'x', except now you're
good-intentioned early calls to the
close() methods of 'y' and 'z' won't
execute until their destructors.
No. Dtors for y and z will be called when the stack unwinds provided you have a try-catch block installed around the MyFile ... z.close() part. A better idea would be to put a close in the dtor as well. The dtor for x will not be -- so some cleanup is in order in the catch block.
I suggest you run the following program to better understand dtor-calls in the case of an exception (once as-is and again by uncommenting the S x line):
#include <iostream>
using namespace std;
struct s {
s(int i = 0) : m_i( i ) { cout << __func__ << endl; }
~s() { if (m_i == 0) except(); cout << __func__ << endl; }
void except() { throw 42; }
int m_i;
};
int main() {
try
{
s y(2), z(3);
/* s x */
y.except();
}
catch (...) { cout << "exception\n"; }
cout << "stack unwound\n";
}
You shouldn't throw from a destructor -- so:
If close had calls that threw exceptions, I would swallow them and do one of the following:
Option 1: Write out an error message and kill the program.
Option 2: Make the error available via a wrapper object (I would probably do this) or a global variable or (prefferably) a variable that is in thread local memory.
Option 1 and 2 both seem reasonable here.
With option 2 and the wrapper you would do:
WrapFileX.close();
WrapFileY.close();
WrapFileZ.close();
if(WrapFileX.hasError || WrapFileY.hasError || WrapfileZ.hasError)
{ //log
exit(1)
}
In this example, I don't see why anything should be thrown. I don't think that this scenario is exception-worthy at all. In theory, the close didn't fail, it just failed to write the rest of the buffer; which isn't a very exceptional situation. It can be handled and should be handled, unless there's a reason that the file needs to be closed right this instant.
I, personally, would just have my close() function block until the writes have completed, then continue with closing.
The rule as I see it is:
If you don't care about the exception then let the destructor do the close work (and catch and discard the exceptions). If you do care (AND can do something about it) then close manually and catch the exception and do the appropriate work.
{
std::fstream X("Plop_X");
std::fstream Y("Plop_Y");
std::fstream Z("Plop_Z");
// Do work
try
{
X.close();
}
catch(Plop const& e)
{
// Fix the exception
// Then make sure X closes correctly.
// If we can't fix the problem
// rethrow
if (badJuJu)
{ throw;
}
}
// Don't care about Y/Z let the destructor close them and discard the exception.
}
try {
x.close();
y.close();
z.close();
}
catch {
//do what ever you need to do here, then close() what' you'll need to close here
}
That's what i would do ,the point is maybe you don't know which one throw the exceptions, and which one left for closing.
First, MyFile's destructor should catch the exception (and that's an incredibly strong "should" - it's not "must" because the behaviour if it doesn't is well-defined, but it's almost never desirable):
~MyFile() {
try {
close();
} catch(...) {}
// other cleanup
}
Next, callers should decide whether they want to handle the error. If they don't, then they can just let the destructor be called. If they do, then they have to call close themselves. If your example of three files, supposing that once one of them has failed you don't care about the others, you can do this:
MyFile x(0), y(1), z(2);
try {
x.close();
y.close();
z.close();
} catch(...) {
std::cerr << "something failed to close\n";
}
If you want to know exactly which failed, you need to ensure that all three close functions are actually called:
MyFile x(0), y(1), z(2);
try {
x.close();
} catch(...) {
std::cerr << "x failed to close\n";
}
try {
y.close();
} catch(...) {
std::cerr << "y failed to close\n";
}
try {
z.close();
} catch(...) {
std::cerr << "z failed to close\n";
}
Of course you might want to common up that code a bit. Also, if you know everything close can throw, then you could have a better catch clause than (...).
This is possibly why the close() function of streams in the standard library doesn't throw an exception unless that behaviour has been enabled by the user setting the exception mask.

Reasons for stack unwinding fail

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.