Call-stack for exceptions in C++

后端 未结 10 1376
忘了有多久
忘了有多久 2020-12-14 15:33

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,

相关标签:
10条回答
  • 2020-12-14 15:53

    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.

    0 讨论(0)
  • 2020-12-14 15:54

    There's a nice little project that gives a pretty stack trace:

    https://github.com/bombela/backward-cpp

    0 讨论(0)
  • 2020-12-14 15:58

    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.

    0 讨论(0)
  • 2020-12-14 16:05

    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.

    0 讨论(0)
提交回复
热议问题