Call-stack for exceptions in C++

后端 未结 10 1375
忘了有多久
忘了有多久 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:41

    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"
    
    0 讨论(0)
  • 2020-12-14 15:43

    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.

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

    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.

    0 讨论(0)
  • 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.

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

    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.

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

    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.

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