Is there a better way to see which function caused a exception other than using catch - c++

I'm having problems with locating the address from which a error occurred, my whole code is running inside of a "try" statement and sadly whenever something is wrong I need to find the error using the old try and fail method by deleting parts of my code. Is there a better way to do it?
My current code:
try
{
do
{
if (somefunction)
if (somefunction2)
if (somefunction3)
if (somefunction4)
}
while (false);
}
catch (...)
{
// todo: somehow get the address where the error occurred
Logger::Log("Exception\n");
}

A simple solution to find out where an exception comes from is to use a unique message within each function. Catch the exception object and print the message. Or perhaps use even a different type of exception which will allow you to efficiently handle each case differently if that's what you want to do.
As for getting an "address", the trace of function calls that lead to the current point of execution is called a stacktrace (or backtrace). The stacktrace would contain information such as addresses. Theres no standard way to get a stacktrace yet, although it has been proposed for C++23.
However, once you've caught the exception, the stack will have been "unwound" such that you can't know where the exception came from. What you could do, is get the stack trace in the code that may be throwing (each of them since you don't know which one is the thrower) and store the trace in the exception. A central place to do that would be within the constructor of a custom exception type. This pattern is common in standard exception handling of modern languages.
Lastly, you don't necessarily need to make any changes to the program, if you instead run the program in a debugger and break on a throw, you can get all the information you can possibly get.

Related

Reasoning behind C++ active exception mechanism

I recently learned that in C++ there is a single "slot" for an active exception and this raise some questions for me.
The example that I know is something like:
void f()
{
MyClass c;
throw MyException;
}
When we get to the throw the function immediately returns and then the exception starts looking for its matching catch. But let's say that during the return of f, when the destructor of c is called, suppose it throws another exception of type MyException2, in this case from what I understood the program always crashes because there is only one "slot" for an active exception so when MyException2 occurs there is a problem.
I would like to know if there is a reason for this specific approach since most other languages have some sort of stack and give a message like During handling of this exception this other exception occurred, with clear stack traces for both exceptions.
Is there a reason for this problem not being approached? Things like a stack of active exceptions and if MyException2 occurs while MyException1 is active then it will just resolve and then return to the handling of MyException1?
I'm sorry if I may not be familiar with the proper terms, this is a purely education question from someone who wishes to know more about the "guts" of the language out of pure fascination.
What you’re thinking about in, say, Python looks like
try: risky()
except Error as e:
some_cleanup(e)
also_risky() # raises OtherError
if still_unhappy(): raise
more_handling()
The corresponding code in C++ behaves the same way and does not automatically terminate:
try {risky();}
catch(const Error &e) {
some_cleanup(e);
also_risky(); // throws OtherError
if(still_unhappy()) throw;
more_handling();
}
The reason is that the original exception might or might not have been handled successfully (is more_handling necessary, or is it just part of retrying?). C++ makes the optimistic statement that it was, whereas by default Python 3 makes the pessimistic statement that the new exception is fallout from the old. C++ could of course provide a syntax to indicate the other choice, like Python does (raise new from None), but such an “associated exception” would be more difficult still to deal with in a static-typing context than exceptions already are, and one of the main motivations is absent since C++ expects the program to provide whatever backtrace-reporting mechanisms are desired.
The parallel is stronger if you consider destructors in both languages (especially in CPython where many of them are reliably invoked during stack unwinding): here, Python simply prints to standard error if a destructor throws, because to do otherwise would greatly complicate its internal resource management. C++ is actually more permissive in that a destructor can throw so long as it was not invoked directly by the unwinding mechanism; this is dangerous, but is occasionally used by experts to good effect. On the other hand, C++ most certainly does not consider writing to standard error a sufficient option for handling an exception, so if its resource management encounters such a problem, it’s all over.

Why wouldn't you declare main() using a function-try-block?

There are a few SO posts about whether or not declaring main() using function-try-block syntax is valid syntax, and the general consensus seems to be that it's perfectly valid. This left me wondering... is there any reason (performance, style, thread synchronization, multithreading) why one wouldn't use this syntax for main() as a general rule to catch any unhandled exceptions anywhere more gracefully?
Obviously, ideally there won't be unhandled exceptions, but they happen and I think it'd be nice to provide something more informative than the OS-specific default handler. For example, in my case, I'd like to provide a support email address to the user so they can report the crash and have my program submit a log to my cloud-based crash log.
For example, in my case, I'd like to provide a support email address to the user
Well, how are you going to do that in a server with no user-facing interface?
Actually, how are you going to do that even in a process with user-facing components, if you have no way to tell in the catch block what state they're in?
And, for those processes where you can't show the user anything useful (or don't have any concept of a "user" in the first place), what would you do in your catch block that would be better than the default terminate?
As for
... more informative than the OS-specific default handler ...
many OS' default behaviour will be to save a complete snapshot of the process execution state, at the point the un-handled exception is thrown, to a file for debugging. As the developer, I can't think of many default behaviours that would be more informative.
Admittedly I'd prefer something more polished as the end user of a desktop app, but that's a pretty small subset of C++ programs.
You can easily convert
int main() try {
// The real code of main
}
catch (...)
{
}
to
int realMain()
{
// The real code of main
}
int main()
{
try
{
return realMain();
}
catch ( ... )
{
}
}
without losing functionality/behavior.
I am going to guess that whether you use the first version or the second version is a matter of coding practices of a team. From a compiler and run time standpoint, I don't see any semantic difference.
If you happened to have a variable that you want to access in your catch block, you would need the curly braces to provide visibility. But even that could be handled with nested try/catch...
why one wouldn't use this syntax for main() as a general rule to catch
any unhandled exceptions anywhere more gracefully?
compatibility with C.
Sometimes there is no way to handle unhandled exceptions more gracefully.
Obviously, ideally there won't be unhandled exceptions, but they
happen and I think it'd be nice to provide something more informative
than the OS-specific default handler. For example, in my case, I'd
like to provide a support email address to the user so they can report
the crash and have my program submit a log to my cloud-based crash
log.
If unexpected exception happens you can not be sure that it is possible to handle it correctly. What are you going to do if there is a network error exception in your example. And trying to send e-mail causes another exception? There can be other errors when you can not be sure that your data is not corrupted and you can not be sure that your program can run correctly after this error. So if you don't know what error happened it is better to allow your program to crash.
You can implement another "watcher" service that checks if process is running and if it has been crashed it can send e-mail to your users with the logs and core dumps.
If you catch the (otherwise) uncaught object, you won't be able to figure out how the execution reached the throw by inspecting the stack trace, because when exception handler is executed, the stack has already been unwound.
If you let the unexpected exception to be uncaught, you may be able to inspect the stack trace in the terminate handler - this is not guaranteed by the standard, but that's not a big deal since there is no standard way to inspect the stack trace either (in C++). You can either use platform specific API within the program, or an external debugger for the inspection.
So for example in your case, the advantage of not catching the exception would be that you can attach a stack trace to the log entry that you intend to submit.
Also, there are cases where an exception can not be handled by a catch block. For example, when you throw from a destructor that is being executed as a result of throwing an exception. So, to handle these "uncatchable" exceptions, you need a terminate handler anyway, so there is little advantage in duplicating the functionality in the case of uncaught exceptions.
As for the syntax that you use to catch the exception, there is no difference. The case where the function try block is different is a constructor, where it allows catching exceptions thrown by sub object constructors.

In C++, Is it possible to force the user to catch exceptions?

In short, is it possible to get C++ to force the invoker of a method to put a try...catch block?
(To clarify:
I don't necessarily mean the immediate invoker, I mean forcing the fact that it's caught somewhere. Also, I'm talking about forcing at compile time.)
The long:
I've read that it not recommended to use exception specification and that it doesn't work properly anyway (http://4thmouse.com/mystuff/articles/UsingExceptionsEffectively.html)
But the general consensus seems to favor the use of exceptions to return errors over the user of writing methods that return error codes.
So if I'm writing say a library, what's to stop the user from calling my method without putting any try...catch blocks, and then getting his program crashing when my code throws an exception?
(To be clear, I only require the exception to be caught somewhere in the users stack, not necessarily in the immediate calling code, and the compiler to complain if this is not the case.)
No, it is not.
Indeed, there is no mechanism to force the caller of a function (anywhere in the call stack) to handle any kind of error. At least, not via a compilation failure. Return values can be discarded. Even bundling error codes with return values (via expected<T, E>) doesn't issue a compile-time error if the user doesn't actually check to see if the value is available before fetching it.
C++17 may give us the [[nodiscard]] attribute, which allows compilers to issue a warning if a return value (presumably an error code) is discarded by the caller. But a compile-time warning will be as close as you can get.
In short, is it possible to get C++ to force the invoker of a method
to put a try...catch block?
No. This would defeat the whole purpose of exceptions. Exceptions are specifically made for the use case of propagating errors across multiple layers without the intermediate layers being aware of them.
Let's say you have a call hierarchy like A -> B -> C -> D -> E, and an error occurs in E. A can handle the error. B, C and D do not need to be aware of the error at all. This is exactly what exceptions are good for!
If you want to return an error directly to the caller because handling the error is indeed the caller's concern, then an exception is often the wrong design and a return value might be the better choice.
"Enforced" exceptions of a certain form have been tried in Java, but I'd consider it a failed experiment, as it usually results in code like this:
try {
method();
} catch (SomeCheckedException ex) {
// ignore
}
That C++ does not encourage this should be considered a feature.
I've read that it not recommended to use exception specification and
that it doesn't work properly anyway
Exactly. The only exception specification which was ever useful and which worked was throw() to signal that no exception at all is thrown, and that one has been superseded in C++11 by noexcept.
But the general consensus seems to favor the use of exceptions to
return errors over the user of writing methods that return error
codes.
See above. It depends on whether you want an error to propagate or if the caller can and should handle it.
So if I'm writing say a library, what's to stop the user from calling
my method without putting any try...catch blocks, and then getting his
program crashing when my code throws an exception?
A library which requires its user to surround all function calls with try blocks has a bad interface and should be redesigned, accordingly.
Also... you assume that a "program" will use your library. But this assumption will not always be true. The library client may itself be a library. There may be a lot of different library layers between the program and your library. You use exceptions if you do not care which layer handles them.
There's a general consensus? Not that I'm aware of. As for the exceptions, no. The compiler cannot enforce that somebody catches the exception somewhere up the call stack. At compile time, the compiler has no idea who may be calling your function, and your function may throw any arbitrary exception, as may any function that your function calls. The linker might have a chance, but it would have to maintain a lot of extra information dealing with what exceptions a function may throw, as well as what exceptions a function may catch. This gets even uglier when you start to talk about dynamically loaded libraries (DLL/.so) as that would have to get resolved at runtime.

lldb - breaking before C++ exception thrown

In lldb I'd like to break before C++ throws the exception, on when the actual signal is generated. I'd like to do this for any type of exception.
The following command will break on the C++ throw catcher
break set -E c++
I'd like to break on the cause of the exception and ignore the C++ throw/catch as if the application was crashing. I'd also like to do this for applications without source.
Is there any lldb voodoo I can use here?
I'm not entirely sure what you are asking.
Exceptions throws in C++ do two things, create the exception object, and then directly call some runtime routine (__cxa_throw on most Unixen) to implement the unwinding. The latter is the point where the exception breakpoint stops. There isn't any more preliminary than this that you could hook onto.
You could try breaking when the exception object is allocated. On OS X & Linux this is __cxa_allocate_exception, but I don't know if that will always get called or if there are alternate ways to make the exception... I don't see how you would gain much from that, however, it's just a couple of instructions later that you'll see the call to the throw method.
But maybe if you describe the problem you are actually trying to solve, we can answer more helpfully...

How to change my error handling method

I can't seem to get my head around why people say C++ exceptions are better. For example, I have an application which loads function objects from shared objects to be used in the application. What goes on is something like this:
bool LoadFunctions()
{
//Get Function factory.
FunctionFactory& oFactory = GetFunctionFactory();
//Create functions from the factory and use.
}
FunctionFactory& GetFunctionFactory()
{
//Get shared object handle.
void* pHandle = dlopen("someso.so");
//Get function ptr for Factory getter.
typedef FunctionFactory* (*tpfFacGet)();
tpfFacGet pF = static_cast<tpfFacGet>(dlsym(pHandle, "GetFactory"));
//Call function and return object.
return *((*pF)());
}
Now, it's easy to see that loads of stuff can go wrong. If I did it like I always do, I'd return pointers instead of references, and I'd check if they were NULL and print an error message and get out if they weren't. That way, I know where things went wrong and I can even try to recover from that (i.e. If I successfully load the factory and fail to load just a single function, I may still continue). What I don't understand is how to use exceptions in such a scenario and how to recover the program rather than printing an error message and qutting. Can someone tell me how I am to do this in C++ish way?
We don't even need return codes. If a problem occurs it should be in the exception.
int main()
{
try
{
LoadFunctions();
// if we're here, everything succeeded!
}
catch(std::exception _e)
{
// output exception message, quit gracefully
}
// IRRESPECTIVE OF SUCCESS/FAILURE WE END UP HERE
return 0;
} // eo main
EDIT:
Okay, so lets say that you have an alternative method of loading functions should LoadFunctions() fail. You might be tempted to call that in the catch handler, but this way you'll quickly end up with a huge amount of nested exception handlers which just complicates things.
So now we get down to the question of design. LoadFunctions should succeed if functions are loaded and throw out an exception if it does not. In this hypothetical example of an alternative method of loading functions, that call should be within the LoadFunctions method. This alternative method does not need to be visible to the caller.
At the top level we either end up with functions, or we do not. Writing good exception handling, in my opinion is about getting rid of grey areas. The function did what it was told to do, or it didn't.
There is, as you say, a lot that can go wrong. You won't catch a bad cast there by the way. If the symbol exists but is not the type you are casting it to, you will just get a nasty shock later.
If you were to avoid exceptions you will need somewhere to report the error. As your LoadFunctions and GetFunctionFactory() do not know how you wish to handle the error (log it? print it to stderr? Put up a message box?) The only thing it can do is generate the error.
A common way do to that in C is to pass in a parameter into which it can put the error if one occurs, and for each function to "check" success before continuing. This can make the flow rather tricky.
The C++ concept of "throwing" the exception means that you do not need to keep passing a pointer (or reference) through each function. Where the error occurs you generate it and "throw" it - a bit like "shouting" it. This causes all code (other than cleanup in destructors) to halt until it finds a catcher that handles the error the way that is required.
Note that exceptions should only generally be used to handle errors, not a normal occurrence like encountering "end of file" when this is the way you know a read has completed.
Using exceptions instead of return-values (or any other method) is not supposed to change the behaviour of the code, only how it is written and organized. That means basically that first you decide what your recovery of a certain error is, be it more graceful or less, then you write the code to perform that.
Most experienced programmers (all practically) agree that exceptions are a much better method than return values. You can't see the big difference in short examples of a few functions, but in real systems of thousands of functions and types you would see it clearly. I will not get into more details of how it is better.
I suggest anyway you should just get yourself used to using exceptions by default. However note that using exceptions has some somewhat delicate issues (e.g. RAII http://en.wikipedia.org/wiki/RAII), that ultimately make your code better, but you should read about them in a book (I won't be able to describe here and feel that I do justice to the subject).
I think the book "Effective c++ / Scott Meyer" deals with that, certainly "Exceptional C++ / Herb Sutter". These books are a good jump start for any c++ developer if you havent read them anyway.