Is Ogre's use of Exceptions a good way of using them? - c++

I've managed to get through my C++ game programming career so far virtually never touching exceptions but recently I've been working on a project with the Ogre engine and I'm trying to learn properly. I've found a lot of good questions and answers here on the general usage of C++ exceptions but I'd like to get some outside opinions from here on whether Ogre's usage is good and how best to work with them.
To start with, quoting from Ogre's documentation of it's own Exception class:
OGRE never uses return values to indicate errors. Instead, if an error occurs, an exception is thrown, and this is the object that encapsulates the detail of the problem. The application using OGRE should always ensure that the exceptions are caught, so all OGRE engine functions should occur within a try{} catch(Ogre::Exception& e) {} block.
Really? Every single Ogre function could throw an exception and be wrapped in a try/catch block? At present this is handled in our usage of it by a try/catch in main that will show a message box with the exception description before exiting. This can be a bit awkward for debugging though as you don't get a stack trace, just the function that threw the error - more important is the function from our code that called the Ogre function. If it was an assert in Ogre code then it would go straight to the code in the debugger and I'd be able to find out what's going on much easier - I don't know if I'm missing something that would allow me to debug exceptions already?
I'm starting to add a few more try/catch blocks in our code now, generally thinking about whether it matters if the Ogre function throws an exception. If it's something that will stop everything working then let the main try/catch handle it and exit the program. If it's not of great importance then catch it just after the function call and let the program continue. One recent example of this was building up a vector of the vertex/fragment program parameters for materials applied to an entity - if a material didn't have any parameters then it would throw an exception, which I caught and then ignored as it didn't need to add to my list of parameters. Does this seem like a reasonable way of dealing with things? Any specific advice for working with Ogre is much appreciated.

You don't need to wrap every last call to Ogre in try { ... } catch. You do it wherever you can meaningfully deal with the exception. This may be at the individual call site in some cases, or it could be in a high-level loop of some sort. If you can't deal with it meaningfully anywhere, don't catch it at all; let the debugger take over.
In particular, you shouldn't catch exceptions in main() for precisely the reason you cite (at least, not during development; you should in production).

I don't know anything about Ogre, I'm afraid, but the general rule with exception handling is that you catch the exception as far as possible from the throw site, but no further. However, this is only possible if the code that throws the exception uses RAII to look after allocated resources. If the code uses dynamic allocation to plain pointers, or other forms of manual resource management, then you need try-blocks at the call site. If this is the case, I'd say use of exceptions is a bad idea.

You seem to be unaware of how to debug exceptions.
Either
Bring up the VS Debug/Exceptions
dialog and tick the C++ Exceptions
box. This will give you an
opportunity (a dialog appears) to debug when an
exception is thrown.
or
If you've built Ogre source, set a
breakpoint in the Ogre::Exception
constructor and when it attempts to throw one you'll break with
a call stack where the next level up is the throw site.

Related

What are the possible error handling strategies using Exceptions in C++, and what are their consequences and implications?

I would like your help in understanding what are the possible approaches to using/disabling exceptions in C++.
My question is not about what is the best choice but just about what are the possible options and what these options imply.
Currently, the options I can think of are:
Compiling with -fno-exceptions and giving up most std containers (possibly defining internal containers which do not throw, such as suggested in SpiderMonkey Coding_Style)
Just avoiding to throw and catch in own code, but still using std containers which may throw exceptions. Being happy with the fact that, in the case of exceptions, the program may terminate without stack unwinding, and that even RAII handled external resources may be left hanging. (This seems to be Google C++ approach according to answers to this SO question)
No using exceptions but wrapping all in a catch all std::exception try block just to make sure stack is unwound and RAII handles to external resources are released before program is terminated, as for this Cert C++ rule
As above, but also throwing exceptions which will ultimately result in program termination.
Also using catched exceptions and recovering from exceptions.
I would like to know if my understanding of options is correct, and what I might be missing out or understanding wrong.
I would also like to know whether constraints on granting basic exception safety make sense for options 2-4 (where exceptions always ultimately lead to program termination) or if/how exception safety requirement can be relaxed/restricted to specific cases (e.g. handling external resources, files).
Update
Strictly speaking, when you want to disable exceptions only compiling with no exception support is true way to go, so Option 1. Because when you want to disable exceptions you should also not use or even handle them. Raising an exception would terminate or go to a hard faulty on most implementations instantly, and only by this you would avoid overhead implications like space or performance overhead even how small (see below) they are.
However if you just want to know which paradigms about exception usage are out there, your options are almost right, with the general idea you haven't mentioned of keeping exceptions exceptional and doing things that are likely or even just could throw, at program startup.
And even more in general, in comes to error handling in general: Exceptions are there to handle errors which you come across at runtime and if done correctly errors you can ONLY detect at runtime. You can avoid exceptions by simply making sure to resolve all problems you can detect before runtime, like proper coding and review (code time), using strict types and checks (templates , compile time), and rechecking them again (static analyser).
Update 2
If you understand you wrong about caring about exception safety I would say:
Basically at first it depends whenever you enable exceptions in general: If they are disabled you can't and shouldn't care about exception safety since there are none (or if they try to come into existence, you will terminate/crash/hardfault anyway).
If you enable exceptions but don't use them in your code, like in case 2, 4 and 3, no problem you want to terminate anyway, so missing cleanup code is not relevant (and the stuff in 3. gets still run in any case). But then should make it clear to everybody that you don't want to use them, so they won't try to recover from exceptions.
And if you use them in your code, you should care about exception safety in the way, that when an exception gets thrown, you clean up after your self too, and then its up the main handler or future code changes, when ever you still terminate or can recover. Not cleaning up but still using exception wouldn't make sense. Then you can just stick to option 1.
This should be to my knowledge exhaustive. For more information see below.
Recommendation
I recommend option 4. and I tell you why:
Exceptions are a very misunderstood and misused pattern. They are misused for program flow like the languages Java does in a excessive. They are often forbidden in embedded or safety code because of their nature that is hard to tell which handler will catch it, if there is one, and how long this will take, for which the C++ std just says basically "implementation magic".
Background
However in my reasoning the hate for exceptions is basically a big XY problem:
When people are complaining that their recovery is broken and hard to tell, then the usual problem is that the don't see you can't or should do much about the most exceptions, that's what they are for. However things like a timeout or a closed tcp connection are hardly non normal, but many people use exceptions for that, that would be wrong of course. But if your whole OS tells you that there is no network adapter or no more memory what could you do? The only thing you probably want is trying to log the reason somewhere and this should be done in one try/catch around the main block.
The same is for safety/real-time programs: For the example of running out of memory, when that happens you are **** anyway, the strategy then is to do this stuff at an unsafe initialisation time, in which exceptions are no problem too.
When using containers with throwing members its a similar scenario, what would you be able to do when you would get their error code instead? Not much, thats the reason why you would make sure at code time that there is no reason for errors, like making sure that an element is really in there, or reserving capacity for your vectors.
This has the nice benefit of cleaner code, not forgetting to check for errors and no performance penalty, at least using the common C++ implementations like gcc etc.
The reason of 3. is debatable, you could do this in my opinion too, but then my question is: What do you have to do in the destructors which wouldn't cleanup your operating system anyway? The OS would cleanup memory, sockets etc.. If have a freestanding scenario, the question remains, whenever different: You plan to halt because your UART broke for example, what would you like to do before halting? And why can't you do it in the catch block before rethrow?
To sum up
Has the problem of not using any throwing code, and still be left with the problem of how to handle rare error codes. (Thats why so many C programmers still use goto or long jumps)
Not viable IMHO, worst of both
as mentioned ok, but what do you need to do in your static DTors, what you even un-normal termination wouldn't do?
My favourite
Only if you really have rare conditions that you are actual able to recover from
What I mean as a general advice: Raising and exception should mean that something happened that should never happen in normal operation, but happened due to a unforeseeable fault, like hardware fault, detached cables, non found shared libraries, a programming fault you have done, like trying to .at() at an index not in the container, which you could have known of, but the container can not. Then it is only logical that throw an exception should almost every time lead to program termination/hard fault
As a consequence of compiling with exception support, is that for example for a freestanding ARM program, your program size will increase by 27kB, probably none for hosted (Linux/Windows etc.), and 2kB RAM for the freestanding case (see C++ exception handler on gnu arm cortex m4 with freertos )
However you are paying no performance penalty for using exceptions when using common compilers like clang or gcc, when you code runs normal i.e. when your branches/ifs which would trow an exception, are not triggered.
As a reference i.e. proof to my statements I refer to ISO/IEC TR 18015:2006 Technical Report on C++ Performance, with this little excerpt from 7.2.2.3:
Enable exception handling for real-time critical programs only if
exceptions are actually used. A complete analysis must always include
the throwing of an exception, and this analysis will always be
implementation dependent. On the other hand, the requirement to act
within a deterministic time might loosen in the case of an exception
(e.g. there is no need to handle any more input from a device when a
connection has broken down). An overview of alternatives for exception
handling is given in ยง5.4. But as shown there, all options have their
run-time costs, and throwing exceptions might still be the best way to
deal with exceptional cases. As long as no exceptions are thrown a
long way (i.e. there are only a few nested function calls between the
throw-expression and the handler), it might even reduce run-time
costs.

repackaging exceptions, or keep them intact?

I'm writing some class which has 2 (main) subsystems. A part depends on boost::filesystem while another part depends on tinyxml. (Basically, it reads an xml, and depending on the data of the xml it uses boost::filesystem's functions for more access to other files).
Now both of these are "likely" to throw exceptions. I am wondering how to handle these exceptions:
The class itself -in most circumstances- can't "fix" an exception and has just to throw it back. (Most probable case would be a faulty input from the user).
However what should one do in such a case? - boost::filesystem & tinyxml both have their own exceptions, which aren't completely compatible with each other.
Should I just expect the user of this class to handle boost/tinyxml exceptions? - So far the whole usage of these libraries is hidden for the end user.
Should I repackage the extensions into my own? I'm always hesitant of repackaging, as it means a lot of extra try ... catch blocks.
What do you recommend me?
It's impossible to answer this question without an understanding of your code and your coding guidelines, specifically as they relate to exceptions.
But if your coding guidelines permit exceptions, then I suggest a general rule-of-thumb:
Allow exceptions to propagate until they reach a context in which they can be handled properly. If they never reach a context in which they can be handled properly, allow your program to crash. Get a core dump and debug the problem.
"Handling" an exception in a certain context might be as simple as translation it in to an error code or your own exception class, but in this case you should rethrow the new exception and allow it to propagate to a handler.
Don't implement any form of a catch-all handler for exceptions with the intent of preventing your application from crashing, or even to log the error and die. Instead, implement a system which will generate dumps in the event of an unhandled exception, and let your program die. The dump itself is enough of a log. You don't want a catch-all because your system is in such a corrupted state that it can't be recovered from.
I'd recommend your class throws your own exceptions. This way you can enforce information hiding and your class clients won't depend from the libraries you decide to use.
Do you believe it is relevant to the end-user? Because this is something related to design.
Some libraries when used on windows have their own data, while you can use other error handling methods for verifying. For example, sqlite has its own group of error codes, but you can use GetLastError in order to know why the database was not open.
In your case, the question is: Will you use exceptions in your own class? In this case, its better to provide your own exception. If not, you can permit the user to cach your errors and the exception if he wants to.
Claudio.

Disabling C++ exceptions, how can I make any std:: throw() immediately terminate?

This C++ program is a CGI script, I have no desire to deal with exceptions. I'd rather get a marginal performance boost and let the OS (Linux) handle cleanup after the process dies.
I am using the Standard C++ Library, and want any function to die like in Perl: Whenever it throws an exception. Without unwinding, or running any further code in my process.
How does -fno-exceptions work? If I have no catch at all in my code, and basically pretend like exceptions do no exist. but I do use std:: c++ library which can throw()?
Option #1: Simply never catch exceptions.
Exceptions don't have much overhead when they're not thrown or caught; if you're throwing and not prepared to catch, well, you're doing to die anyway, so the performance impact at that point is trivial. Note also that stack unwinding will not be performed if an exception is not handled; the program will simply terminate without performing stack unwinding.
It's important to note that, in G++, exceptions have almost no overhead when not actually thrown. G++ generates extra information sufficient to trace back the execution of the program through the stack, and some extra code to invoke destructors, etc - however none of this extra code or data is ever used until an exception is actually thrown. So you should not see a performance difference between code with exceptions enabled but not used and code with exceptions disabled (through whatever mechanism).
Option #2: Pass -fno-exceptions.
This flag instructs G++ to do two things:
All exception handling in STL libraries are removed; throws are replaced with abort() calls
Stack unwind data and code is removed. This saves some code space, and may make register allocation marginally easier for the compiler (but I doubt it'll have much performance impact). Notably, however, if an exception is thrown, and the library tries to unwind through -fno-exceptions code, it will abort at that point, as there is no unwind data.
This will, effectively, turn all exceptions into abort()s, as you would like. Note, however, that you will not be allowed to throw - any actual throws or catchs in your code will result in a compile-time error.
Option #3: (Nonportable and not recommended!) Hook __cxa_allocate_exception.
C++ exceptions are implemented using (among others) the __cxa_allocate_exception and __cxa_throw internal library functions. You can implement a LD_PRELOAD library that hooks these functions to abort():
void __cxa_allocate_exception() { abort(); }
void __cxa_throw() { abort(); }
WARNING: This is a horrible hack. It should work on x86 and x86-64, but I strongly recommend against this. Notably, it won't actually improve performance or save code space, as -fno-exceptions might. However, it will allow the throw syntax, while turning throws into abort()s.
-fno-exceptions turns all standard library throw's into a call to std::abort(). That handles the part you can't modify directly, the rest is to not use them at all in your code.
Of course, I really doubt your justification in doing this. You only "lose" performance when you actually throw, and you're throwing out a significant and helpful bit of the language.
In case anyone stumbles upon this question, I'd like to correct what #GManNickG and (https://stackoverflow.com/a/7249460/157344) and #bdonlan (https://stackoverflow.com/a/7249442/157344) said in their answers. Unfortunately the part about "-fno-exception" removing all exception handling code and turning all throws into aborts is wrong. Well - partially wrong. This is true when you compile the library in question (libstdc++v3) with this flag, but not true if you use this library (as an .a or .so or .dll or whatever) in your own code compiled with this flag. In the latter case the exception handling code in YOUR code is forbidden, but all the calls to exception handling inside the library remain (because the library was compiled WITHOUT this flag, with exceptions enabled), so if you use new then your executable WILL have exception handling code - the only difference is that you cannot anything about these exceptions with a catch() (which is forbidden in your code), so all throws effectively end up as abort(), but only because no one catches them.
Quote:
This C++ program is a CGI script, I have no desire to deal with exceptions.
Then don't. Simple. The exception will get to the top of the stack very quickly.
But I would urge you to do so. To do so means that you are thinking of the things that can go wrong.
Just don't catch them anywhere in your code. In that case, a termination handler will be called and your program will "crash".

Call-stack for exceptions in C++

Today, in my C++ multi-platform code, I have a try-catch around every function. In every catch block I add the current function's name to the exception and throw it again, so that in the upmost catch block (where I finally print the exception's details) I have the complete call stack, which helps me to trace the exception's cause.
Is it a good practice, or are there better ways to get the call stack for the exception?
What you are doing is not good practice. Here's why:
1. It's unnecessary.
If you compile your project in debug mode so that debugging information gets generated, you can easily get backtraces for exception handling in a debugger such as GDB.
2. It's cumbersome.
This is something you have to remember to add to each and every function. If you happen to miss a function, that could cause a great deal of confusion, especially if that were the function that caused the exception. And anyone looking at your code would have to realize what you are doing. Also, I bet you used something like __FUNC__ or __FUNCTION__ or __PRETTY_FUNCTION__, which sadly to say are all non-standard (there is no standard way in C++ to get the name of the function).
3. It's slow.
Exception propagation in C++ is already fairly slow, and adding this logic will only make the codepath slower. This is not an issue if you are using macros to catch and rethrow, where you can easily elide the catch and rethrow in release versions of your code. Otherwise, performance could be a problem.
Good practice
While it may not be good practice to catch and rethrow in each and every function to build up a stack trace, it is good practice to attach the file name, line number, and function name at which the exception was originally thrown. If you use boost::exception with BOOST_THROW_EXCEPTION, you will get this behavior for free. It's also good to attach explanatory information to your exception that will assist in debugging and handling the exception. That said, all of this should occur at the time the exception is constructed; once it is constructed, it should be allowed to propagate to its handler... you shouldn't repeatedly catch and rethrow more than stricly necessary. If you need to catch and rethrow in a particular function to attach some crucial information, that's fine, but catching all exceptions in every function and for the purposes of attaching already available information is just too much.
No, it is deeply horrible, and I don't see why you need a call stack in the exception itself - I find the exception reason, the line number and the filename of the code where the initial exception occurred quite sufficient.
Having said that, if you really must have a stack trace, the thing to do is to generate the call stack info ONCE at the exception throw site. There is no single portable way of doing this, but using something like http://stacktrace.sourceforge.net/ combined with and a similar library for VC++ should not be too difficult.
One solution which may be more graceful is to build a Tracer macro/class. So at the top of each function, you write something like:
TRACE()
and the macro looks something like:
Tracer t(__FUNCTION__);
and the class Tracer adds the function name to a global stack on construction, and removes itself upon destruction. Then that stack is always available to logging or debugging, maintenance is much simpler (one line), and it doesn't incur exception overhead.
Examples of implementations include things like http://www.drdobbs.com/184405270, http://www.codeproject.com/KB/cpp/cmtrace.aspx, and http://www.codeguru.com/cpp/v-s/debug/tracing/article.php/c4429. Also Linux functions like this http://www.linuxjournal.com/article/6391 can do it more natively, as described by this Stack Overflow question: How to generate a stacktrace when my gcc C++ app crashes. ACE's ACE_Stack_Trace may be worth looking at too.
Regardless, the exception-handling method is crude, inflexible, and computationally expensive. Class-construction/macro solutions are much faster and can be compiled out for release builds if desired.
The answer to all your problems is a good debugger, usually http://www.gnu.org/software/gdb/ on linux or Visual Studio on Windows. They can give you stack traces on demand at any point in the program.
Your current method is a real performance and maintenance headache. Debuggers are invented to accomplish your goal, but without the overhead.
There's a nice little project that gives a pretty stack trace:
https://github.com/bombela/backward-cpp
Look at this SO Question. This might be close to what you're looking for. It isn't cross-platform but the answer gives solutions for gcc and Visual Studio.
One more project for stack-trace support: ex_diag. There are no macros, cross-platform is present, no huge code needs, tool is fast, clear and easy in use.
Here you need only wrap objects, which are need to trace, and they will be traced if exception occurs.
Linking with the libcsdbg library (see https://stackoverflow.com/a/18959030/364818 for original answer) looks like the cleanest way of getting a stack trace without modifying your source code or 3rd party source code (ie STL).
This uses the compiler to instrument the actual stack collection, which is really want you want to do.
I haven't used it and it is GPL tainted, but it looks like the right idea.
While quite a few counter-arguments have been made in the answers here, I want to note that since this question was asked, with C++11, methods have been added which allow you to get nice backtraces in a cross-platform way and without the need for a debugger or cumbersome logging:
Use std::nested_exception and std::throw_with_nested
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code by simply writing a proper exception handler which will rethrow nested exceptions.
It will, however, require that you insert try/catch statements at the functions you wish to trace.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub or my "trace" library, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
An exception that isn't handled is left for the calling function to handle. That continues until the exception is handled. This happens with or without try/catch around a function call. In other words, if a function is called that isn't in a try block, an exception that happens in that function will automatically be passed up to call stack. So, all you need to do is put the top-most function in a try block and handle the exception "..." in the catch block. That exception will catch all exceptions. So, your top-most function will look something like
int main()
{
try
{
top_most_func()
}
catch(...)
{
// handle all exceptions here
}
}
If you want to have specific code blocks for certain exceptions, you can do that too. Just make sure those occur before the "..." exception catch block.

C++ exception handling with source code line info

Is there a way catch an exception like access violation and get information about on which line an exception occurred? This would be very good for debugging purposes, especially for testers..
My environment is Windows with VC++ on VS2008
An access violation is not an exception in C++ terms, so the answer is in general "no". Concieveably, your specific implementation might have a feature that turns access violations into C++ exceptions - you need to specify what compiler & platform you are using.
In case you really want to log info about C++ exceptions (AV is not one) thrown from your code, you can use macros __FILE__ and __LINE__ within constructors of your exception types.
If you catch the SEH exception using a __catch handler you can then access the thread context at the time of the exception and then use StackWalk64 to dump the call stack at the point where the exception was generated. Note that as I mentioned here: Printing the stack trace in C++ (MSVC)? StackWalker by Jochen Kalmbach [MVP VC++] and available on codeproject is probably the easiest way to do this. It wraps up all of the details of dealing with the underlying StackWalk64 API.
Alternatively you could the same solution that I proposed here: How to catch divide-by-zero error in Visual Studio 2008 C++? to convert the Windows Structured Exceptions into C++ exceptions and capture the stack trace as shown above at the point where you translate the exception. This would give you a C++ exception with a stack trace like you get in C# or Java.
I'm not sure why testers would need to know which line an exception occurred.
The developers might want to know, though. But a better approach is the following:
Include the information about class and method with each PROGRAM exception. These are exceptions that should NOT have happened.
This should be output by whatever logs your exceptions. Your program does catch and log every exception, doesn't it? If not, it should.
Make sure your methods are small enough that the above is enough information to easy track down a bug. If you need line information as well, then your methods are too large and your exceptions are not specific enough.
In MSVC you can set the debugger to break when any exception or things like an access violation happen buy going to debug->Exceptions and checking the appropriate box.
Note that access violations are not C++ exceptions and will be handled differently on different systems. In Windows you can trap them with a structured exception handler. In unixy systems it will usually core dump. You can usually get a stacktrace from that.
For msdev / Windows, during development, always have your linker generate a MAP file.
When Windows throws up an access violation, and it's your code (not library), you can use the address to match up function / data in the MAP file and get within a few lines of the offender. At a minimum, you'll know the function/method.
That's really a compiler question.
If you want to know if it is possible for a compiler to provide, the answer is yes. I know multiple Ada compilers that provide tracebacks for unhandled exceptions, so it is clearly possible. This includes the gcc-based Gnat, so if the C++ compiler uses any of the same facilities for its exceptions, the support for doing that should already be there.
On unix type systems a Access violation generates a SEGV or BUS signal. This normally causes the application to core dump. You could always write your own signal handler. From there you could probably generate a stack-dump using the glibc before core dumping.
A core dump generally give you all this for wasy analysis in gdb.
My answer refers to Windows only. You have quite a few options:
Without changing your code -
Avoid catching exceptions (at least ones you do not expect), and let your app just crash. Configure good ol' dr. watson (drwtsn32.exe) to create a crash dump, and open that dump in your debugger. You'll get the exact line of code there.
Use adPlus (from the windbg installation) to monitor your app's run, and create a dump when an exception is thrown.
From within your code, you can -
Easily walk the stack when a structured exception is thrown. See Jochen Kalmbach's stack walker for example.
Use this weird hack to walk the stack when a C++ exception is thrown.
Finally, quite a lot of questions have been asked here on this issue. Look around, and you'll get additional answers.
On one project I worked on, the root class of the exception hierarchy used captured a callstack in the constructor in case that information was needed later for debugging after the exception was caught. It was a decent idea, although if you're catching and 'handling' the exception, exactly when it was thrown shouldn't really matter all that much.
To put it another way, if you care about this info (context of "who" threw it), you probably shouldn't be using an exception to report this condition, or potentially you shouldn't be catching the exception in the first place. Uncaught exceptions cause crashes, giving you a crash dump at the point the exception was thrown.
On windows, the C runtime system function _set_se_translator() takes a simple static function with signature
void f(int, EXCEPTION_POINTERS*)
neither of which argument you totally need. In the body of f, throw your favorite exception. Call the function near the beginning of your program. The documentation is reasonable for microsoft.
You can do all manner of additional stuff with this function.
The google breakpad project has many good things. Among them are means to convert a crash address to file, line, and function name using build symbols and the debuginfo dll.