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.
Related
If you throw an unhandled exception out of main like this:
#include <stdexcept>
#include <iostream>
int main()
{
std::cout << "Hello World 1" << std::endl;
throw new std::invalid_argument("A");
return 0;
}
... then the process will terminate with the message "terminate called after throwing an instance of 'std::invalid_argument*'".
You will actually see this on the console:
Hello World 1
terminate called after throwing an instance of 'std::invalid_argument*'
If you print some more text without std::endl and then throw the exception:
#include <stdexcept>
#include <iostream>
int main()
{
std::cout << "Hello World 1" << std::endl;
std::cout << "Hello World 2";
throw new std::invalid_argument("A");
return 0;
}
... then you won't see the second line on the console:
Hello World 1
terminate called after throwing an instance of 'std::invalid_argument*'
It seems that this error message overwrites the last line, e.g. by printing \r before it.
How can this behavior be fixed?
The second line is not actually overwritten by the message, it never reaches the console!
The problem is that std::cout buffers its output and that this buffer is not flushed if the process terminates. (The error message is actually printed to standard error, not standard output.) And that problem was already discovered:
Is it possible to make std::cout flush automatically before program termination in various failure cases (e.g., exception)
In my case I used this to forcefully flush the buffer:
std::terminate_handler oldTerminateHandler;
void newTerminateHandler()
{
std::cout << std::endl;
if (oldTerminateHandler != nullptr)
{
oldTerminateHandler();
}
}
int main()
{
oldTerminateHandler = std::set_terminate(&newTerminateHandler);
//...
}
<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.
At a point in my code, I pass a *this to a method foo(const MyClass& arg). An exception is thrown deep inside this foo, but although a syntactically correct try-catch block exists up the stack, it gets neither handled (a message should have been emitted in that case), nor the process crashes. From the debugging logs, I can see that related thread gets stuck, although the rest of the threads keep going.
I've been through stack unwinding documentation, and somewhere I've seen that arguments to functions are also considered to be auto variables, and get destroyed during the unwinding process. That brings me to the question: what happens when I pass a const reference of this (inside which there is a corresponding catch block) to a method where an exception is thrown? Is it possible that the ref gets the caller object destroyed, and catch block is now unreachable even though stack unwinding has begun already?
Let me add some pseudoish-code:
void MyClass0::someFunc(void)
{
try
{
MyClass1 obj1;
obj1.someOtherFunc(*this);
// Some other stuff
}
catch (MyException&)
{
std::cout << "Handling exception...";
// Whatever... This message is not emitted.
}
}
void MyClass1::someOtherFunc(const MyClass0& argObj0)
{
// Some functions that eventually throw an unhandled MyException
}
Thanks in advance...
EDIT:
OK, trying to generate an executable code for reference, I believe I pretty much answered my own question.
Here's the code:
#include "sandbox.h"
#include <iostream>
MyClass0::MyClass0(void)
{
std::cout << "\nConstructing MyClass0";
}
MyClass0::~MyClass0(void)
{
std::cout << "\nDestructing MyClass0";
}
void MyClass0::trustIssues(void)
{
std::cout << "\nEntering " << __FUNCTION__;
try
{
MyClass1 myClass1;
myClass1.unwaryFunction(*this);
}
catch (MyException& exc)
{
std::cout << "\nException caught in " << __FUNCTION__;
std::cout << "\nLeaving " << __FUNCTION__ << " from inside catch block.";
return;
}
std::cout << "\nLeaving " << __FUNCTION__;
}
MyClass1::MyClass1(void)
{
std::cout << "\nConstructing MyClass1";
}
MyClass1::~MyClass1(void)
{
std::cout << "\nDestructing MyClass1";
}
void MyClass1::unwaryFunction(MyClass0& argClass0)
{
std::cout << "\nEntering " << __FUNCTION__;
suicidalFunction();
std::cout << "\nLeaving " << __FUNCTION__;
}
void suicidalFunction(void)
{
std::cout << "\nEntering " << __FUNCTION__;
MyException myException;
throw myException;
std::cout << "\nLeaving " << __FUNCTION__;
}
int main(int argc, char* argv[])
{
MyClass0 myClass0;
myClass0.trustIssues();
return 0;
}
The output has been:
Constructing MyClass0
Entering MyClass0::trustIssues
Constructing MyClass1
Entering MyClass1::unwaryFunction
Entering suicidalFunction
Destructing MyClass1
Exception caught in MyClass0::trustIssues
Leaving MyClass0::trustIssues from inside catch block.
This implies that the *this argument does not get destroyed on stack unwinding of unwaryFunction. I probably have some other bug in the actual code (as the message analogous to "Exception caught in..." does not get printed). I'll keep this question for future reference. Thanks for your concern anyway.
I have been learning c++ recently and while working on exceptions, I came across something that confuses me. I threw a string exception and added multiple catch blocks to see how it works, and for some reason, the string exception is being caught in the int catch block. This is puzzling me and I cant see to find reasons why it would do it.
FYI, I am using GCC v 5.3.0
So, I was expecting the following message on the console.
String exception occurred: Something else went wrong
But instead, I got the following message.
Int exception occurred: 14947880
So I tried switching the order of the catch blocks and placed the string catch block on the top, and I got the string exception message. Could somebody please explain a reason why this is happening? It seems whatever catch block is in the top is being caught first.
I don't think this is the correct behavior and that the string exception block should be executed, but if I am wrong, please correct me. Thanks for taking time to look at this.
#include <iostream>
using namespace std;
void MightGoWrong()
{
bool error = true;
if (error)
{
throw string("Something else went wrong");
}
}
/**
* Output on console: Int exception occurred: 14947880
*/
int main() {
try
{
MightGoWrong();
}
// If string or char pointer catch block goes to top, that block will execute
catch (int e)
{
cout << "Int exception occurred: " << e << endl;
}
catch (string &e)
{
cout << "String exception occurred: " << e << endl;
}
catch (char const * e)
{
cout << "Char exception occurred: " << e << endl;
}
return 0;
}
I have a sample code to modify and throw exception handling. The problem is even after I threw an exception, the code still returns a random 0. I have spent some time trying to figure out why I still have a 0 returned but I could not find the answer. Does anyone have an idea why the code behaves like this?
#include <stdexcept>
#include <iostream>
#include <string>
using namespace std;
struct myException_Product_Not_Found : exception
{
virtual const char* what() const throw() {
return "Product not found";
}
} myExcept_Prod_Not_Found;
int getProductID(int ids[], string names[], int numProducts, string target) {
for (int i=0; i<numProducts; i++) {
if(names[i] == target)
return ids[i];
}
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
}
// Sample code to test the getProductID function
int main() {
int productIds[] = {4,5,8,10,13};
string products[] = {"computer","flash drive","mouse","printer","camera"};
cout << getProductID(productIds, products, 5, "computer") << endl;
cout << getProductID(productIds, products, 5, "laptop") << endl;
cout << getProductID(productIds, products, 5, "printer") << endl;
return 0;
}
getProductID doesn't throw an exception. You catch the exception you do throw before getProductID has a chance to throw it. As such, you return ... well, nothing. The functions ends without you calling return.
If you had turned on your compiler's warnings* (as should should be doing), the compiler should warn with a message like control reaches end of non-void function. g++ appears to return zero in this instance, but returning zero is probably undefined behaviour.
If you want a function to throw an exception, don't catch the exception you've thrown inside of the function. Move the catch to the outside.
int getProductID(...) {
...
throw myExcept_Prod_Not_Found;
}
string product = "computer";
try {
cout << getProductID(productIds, products, 5, product) << endl;
} catch (exception& e) {
cout << "Can't find product id for " << product << ": " << e.what() << endl;
}
* — To turn on warnings in g++, -Wall is a good starting point. #Tomalak Geret'kal suggests -Wall -Wextra -std=c++98 -pedantic or -Wall -Wextra -std=c++0x -pedantic.
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
Here you're throwing an exception and then immediately catching it. The exception message is output to console and then execution of your function continues as normal... except you have no value to return.
So, the result of that function call is unspecified, and you're seeing some arbitrary rubbish from memory as well as invoking undefined behaviour.
Instead, just let the exception propogate right up the callstack by not catching it: it'll lead your program to terminate (possibly without actually unrolling, incidentally):
throw myExcept_Prod_Not_Found;