VC++ exception handling - app crashes anyway - c++

Following is the code snippet I have written in the process of learning exception handling in C++(using visual studio 2010 compiler).
#include "stdafx.h"
#include <iostream>
using namespace std;
void multi_double() {
double first,second,product;
try{
cout << "Enter the first number\n";
cin >> first;
cout << "Enter the second number\n";
cin >> second;
product = first * second;
cout << product;
}
catch(...){cout << "Got an exceptional behaviour";}
}
void stud_age(){
int age;
try{
cout << "Enter student's age\n";
cin >> age;
if(age < 0)
throw;
cout << endl <<age;
}
catch(...) {
cout << "Caught here\n";
}
}
class Model{
public:
Model(){cout << "ctor\n";}
~Model(){cout << "dtor\n";}
};
int _tmain(int argc, _TCHAR* argv[]) {
//multi_double();
//stud_age();
int a;
try{
Model obj;
int *p = NULL;
*p = 0;//expecting access violation exception
}
catch(...){
cout << "caught an exception\n";
}
return 0;
}
Enable C++ exception is set to Yes[/EHsc].
But when I run the application,it is still crashing anyway ! with following information:
Problem signature:
Problem Event Name: APPCRASH
Application Name: DataTypeConversions.exe
Application Version: 0.0.0.0
Application Timestamp: 4ffd8c3d
Fault Module Name: DataTypeConversions.exe
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 4ffd8c3d
Exception Code: c0000005
Exception Offset: 00001051
Why is not control coming to catch block?!

Access Violations and all other kinds of hardware exceptions are handled in Windows using a mechanism called "C Structured Exception Handling (SEH)". This was originally designed to give C programs a more "structured" way to handle exceptions than the usual signal()/sigaction() mechanism in Posix based systems.
SEH exceptions can be integrated into the C++ Exception system, by setting a translator function which is called before SEH stack unwinding takes place. The new translator function simply throws a C++ exception and, presto, C++ can catch the error!
See this Document from the MSDN for all the details:
http://msdn.microsoft.com/de-de/library/5z4bw5h5(v=vs.80).aspx
And here's a working example:
#include <windows.h>
#include <iostream>
#include <eh.h>
// You need to enable the /EHa excpetion model to make this work.
// Go to
// Project|Properties|C/C++|Code Generation|Enable C++ Exceptions
// and select "Yes with SEH Exceptions (/EHa)"
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
// printf( "In trans_func.\n" );
throw "Hardware exception encountered";
}
int main()
{
_set_se_translator(trans_func);
try
{
int *p = NULL;
*p = 0;//expecting access violation exception
}
catch(const char *s)
{
std::cout << "caught an exception:" << s << "\n";
}
return 0;
}

The C++ exception handling system can not hardware-generated (ie. access violation etc) exceptions, only exceptions generated by code through throw exception;.
If you want to catch these exceptions, it is only possible in Windows through the use of structured exceptions. This is not compatible with other compilers and uses the __try __except construct rather than normal try / catch.

Related

Do you need to know what exception is going to occur to handle them in C++?

<C++>In exception handling, do you need to know what exception and where an exception is going to occur? Can you make a code which will print and notify us that an exception occurred somewhere in the program. I mean I have a program in which I don't know if an exception will occur or not, if one was to occur, then it will print to notify us.
Exception handling is something you should design for, and in fact it works very well together with RAII (https://en.cppreference.com/w/cpp/language/raii).
(Notr On embedded platforms using exceptions, is not so popular because of some runtime overhead). What I personally like about exceptions is that it separates error handling from the normal program flow (there will be hardly any if then else checks when done right)
// Exception handling should be part of your overal design.And many standard library functions can throw exceptions, It is always up to you where you handle them.
#include <iostream>
#include <string>
#include <stdexcept>
int get_int_with_local_exception_handling()
{
do
{
try
{
std::cout << "Input an integer (local exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
// stoi is a function that can throw exceptions
// look at the documentation https://en.cppreference.com/w/cpp/string/basic_string/stol
// and look for exceptions.
//
int value = std::stoi(input);
// if input was ok, no exception was thrown so we can return the value to the client.
return value;
}
// catch by const reference, it avoids copies of the exception
// and makes sure you cannot change the content
catch (const std::invalid_argument& e)
{
// std::exceptions always have a what function with readable info
std::cout << "handling std::invalid_argument, " << e.what() << "\n";
}
catch (const std::out_of_range& e)
{
std::cout << "handling std::out_of_range, " << e.what() << "\n";
}
} while (true);
}
int get_int_no_exception_handling()
{
std::cout << "Input an integer (without exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
int value = std::stoi(input);
return value;
}
int main()
{
try
{
// this function shows you can handle exceptions locally
// to keep program running
auto value1 = get_int_with_local_exception_handling();
std::cout << "your for input was : " << value1 << "\n";
// this function shows that exceptions can be thrown without
// catching, but then the end up on the next exception handler
// on the stack, which in this case is the one in main
auto value2 = get_int_no_exception_handling();
std::cout << "your input was : " << value1 << "\n";
return 0;
}
catch (const std::exception& e)
{
std::cout << "Unhandled exception caught, program terminating : " << e.what() << "\n";
return -1;
}
catch (...)
{
std::cout << "Unknown, and unhandled exception caught, program terminating\n";
}
}
Yes and no.
No, because any exception thrown via throw some_exception; can be catched via catch(...).
Yes, because catch(...) is not very useful. You only know that there was an excpetion but not more.
Typically exceptions carry information on the cause that you want to use in the catch. Only as a last resort or when you need to make abolutely sure not to miss any excpetion you should use catch(...):
try {
might_throw_unknown_exceptions();
} catch(std::exception& err) {
std::cout << "there was a runtime error: " << err.what();
} catch(...) {
std::cout << "an unknown excpetion was thrown.";
}
The C++ standard library uses inheritance only sparingly. Exceptions is only place where it is used extensively: All standard exceptions inherit from std::exception and it is good practice to inherit also custom exceptions from it.

C++ rethrow does not call custom terminate handler

I have used custom terminate handler which works fine if I call throw with a type or explicitly call terminate(), but if I use rethow i.e throw; , the custom terminate handler is not called, only default terminate handler is called causing the program to abort. Code confirms to C++03. Could anyone help me to find out the problem ? Thank you in advance
#include <iostream>
#include <exception>
using namespace std;
void myunexpected() {
cerr << "CUSTOM unexpected handler called ------ \n";
throw 0; // throws int (in exception-specification)
}
void myterminate () {
cerr << "CUSTOM terminate handler called ------ \n";
//abort(); // forces abnormal termination
exit(0);
}
void myfunction() throw (int) {
throw 'x'; // throws char (not in exception-specification)
}
int main(void) {
set_unexpected(myunexpected);
set_terminate(myterminate);
int a = 1;
try{
try {
myfunction();
}
catch (int) {
cerr << "caught int\n";
throw string("sree");
}
catch (...) { cerr << "caught some other exception type\n"; }
}
catch (string& s)
{
cerr << a << "caught STRING " << s << endl;
//throw 0; //ok --> implicitly calls terminate()-->myterminate
//terminate(); //ok --> explicitly calls terminate()-->myterminate
throw; //--------- Calls default throw Why ???
}
return 0;
}
OUTPUT
CUSTOM unexpected handler called ------
caught int
1caught STRING sree
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
--------------------------------
Process exited after 8.238 seconds with return value 255
Press any key to continue . . .

bad_alloc preempted in VS 2010/2013 C++

This simple example works as expected in g++, but in MS VS 2010 or 2013 shows a runtime library debug error (Invalid allocation size) before the error is caught (clicking Ignore does then flow through the error handler showing it correctly to be a bad_alloc).
Any ideas about why VS behaves this way?
#include <iostream>
#include <exception>
using namespace std;
int main() {
int x;
cout << "Enter -1 for bad_alloc: ";
cin >> x;
try
{
int* myarray = new int[x];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}
That's so that you can analyse the exception at the point it is thrown, before the stack is unwound.
It's a feature that the debugger does this for you.
Nothing to worry about here.

Why does it print out "abracadabra" and not "Timmy"?

This code throws an exception when I enter "Timmy" as the name. I'm really not sure of the mechanism but why does it print out "abracadabra" and not "Timmy". One thing I'm sure of though is that there is no magic going on here!
This is the short code
#include <iostream>
using namespace std;
#include <string>
#include <cstdlib>
string enterName();
void checkName(string);
int main()
{
string someName = "abracadabra";
try {
someName = enterName();
}
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
cout << "Name: "<<someName<<endl;
return 0;
}
string enterName()
{
string s;
cout<<"Enter a name: ";
cin >> s;
cout<<endl;
try {
checkName(s);
}
catch(const char* err) {
cout << "middle man says: "<<err <<endl;
throw "rtetfrer";
}
return s;
}
void checkName(string name)
{
if (name == "Timmy")
throw "Help, Timmy's been kidnapped by a giant squid!";
}
You are throwing an exception, so the function never returns:
void checkName(string name)
{
if (name == "Timmy")
//This throws an exception, so the function exits immediately
throw "Help, Timmy's been kidnapped by a giant squid!";
}
That exception is caught here:
try {
checkName(s);
}
catch(const char* err) {
//This will be the exception that timmy is caught
cout << "middle man says: "<<err <<endl;
//This will throw an exception and immediately exit the function
throw "rtetfrer";
}
//This will never be called
return s;
And the new exception will be caught here:
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
But since checkName never returned a value, somename will still be magic
enterName(); throws an exception before the assignment to someName is made. Hence someName retains its original value.
(In a little more detail: enterName() calls checkName(). checkName() throws an exception since name is "Timmy". enterName() throws "rtetfrer". Why not verify with your debugger?)
In order to assign a value to someName, c++ must first evaluate the expression on the left side. That is the result of the function enterName. Now during the execution of this function an exception is thrown. When this happens the execution jumps right to the catch clause(skipping the return clause of the function and then the assignment of someName to this return value), thus you never assign a different value to someName.
Use a debugger to follow the execution flow in an easier manner.

What do the hex numbers in the "first-chance exception..." messages mean?

For example, in the message:
First-chance exception at 0x757bd36f in foo.exe: Microsoft C++
exception: _ASExceptionInfo at memory location 0x001278cc..
What does 0x757bd36f and 0x001278cc mean? I think that 0x757bd36f would mean the EIP at the time the exception was thrown, but what about the second number?
As you've surmised, the first is the EIP when the exception happened (or RIP, for 64-it code).
Doing some testing, the second number is the address of the exception object being caught. Keep in mind, however, that this is not the same as the address of the exception object that was thrown. For example, I wrote the following bit of test code:
#include <iostream>
#include <conio.h>
class XXX { } xxx;
void thrower() {
throw xxx;
}
int main() {
try {
std::cout << "Address of xxx: " << (void *)&xxx << "\n";
thrower();
}
catch(XXX const &x) {
std::cout << "Address of x: " << (void *)&x << "\n";
}
getch();
return 0;
}
At least in my testing, the second address VS shows in its "first chance exception" message matches with the address I get for x in the code above.