0

I need to implement an exception handling system for a very large C++ code. I need to implement a standard which meets the following specifications:

  • Print out the call trace when an exception is thrown
  • Allow the developer to specify optional additional information about the state of a function when the exception is called. (e.g. the value of a counter during an iteration)
  • Easy to implement (since I will not be able to do it myself)
  • Uninvasive
  • Portable

It seems to me as though putting try/catch blocks in every single function is the only possible solution, but this seems generally fround upon and considered to be bad practice. It is also clumsy and difficult to maintain/implement consistently.

I have also looked into libraries like stacktrace, but they seem limited on portability and I would have to sacrifice the ability for optional additional state information.

Edit: what is the best way to do this?

Mr.P
  • 81
  • 5
  • 4
    so your question is what exactly? – user1231232141214124 May 07 '14 at 00:28
  • "I have also looked into libraries like stacktrace, but they seem limited on portability ..." The C++ standard doesn't specify any way to get the stack trace (not even exceptions), although platforms are free to provide some such way. In other words, any solution that meets your first bullet point won't be completely portable. – Max Lybbert May 07 '14 at 00:35
  • redFIVE: please see edit. – Mr.P May 07 '14 at 01:02
  • 1
    @Mr.P Your _'Off topic'_ moved from "Unclear what you're asking" to "Too broad" now. Sorry :-P ... – πάντα ῥεῖ May 07 '14 at 01:05
  • 1
    Max: that's not quite true. You can use C++ exceptions in your code to get the **call** trace by surrounding each function with a try/catch and using __func__ to print out the function name for each catch. – Mr.P May 07 '14 at 01:05
  • 1
    You're not going to get anywhere without putting more thought into your requirements. Do you need stack traces for throws from Standard and 3rd party libraries? Does the "very large C++ code" consistently throw a custom exception class, and/or use a macro to construct the object or do the throw, or are you able/prepared to change it to do so? Capturing the stack at the point of throwing is cleaner than wrapping every function in a try/catch block. Can you shoehorn the "optional addition information" into a string (e.g. using `ostringstream`)? Many more options.... – Tony Delroy May 07 '14 at 01:43
  • possible duplicate of [C++ display stack trace on exception](http://stackoverflow.com/questions/691719/c-display-stack-trace-on-exception) – jww May 07 '14 at 01:55
  • 1
    Walking the stack to get the stack trace and *portable* might not play very well together... – David Rodríguez - dribeas May 07 '14 at 02:20
  • 1
    @Mr.P: Good luck adding try/catch code to *all* functions in a *very large C++ code*. – David Rodríguez - dribeas May 07 '14 at 02:22
  • 1
    Get your requirements changed. PORTABLE and STACKTRACE are not compatible. UNINVASIVE and C++ STACKTRACE are not compatible. – jmucchiello May 07 '14 at 02:36
  • @Mr.P: thank you. I hadn't thought of that, and while it is labor intensive, it is also fully portable. – Max Lybbert May 07 '14 at 06:30
  • @TonyD: Currently, the code has no error handling at all. I'm looking into setting up a completely new system. Passing stack information as a string is an interesting idea though, I'll look into it. – Mr.P May 08 '14 at 02:07
  • @jww: Not the same thing. I'm interested in portability and adding additional state information (e.g. the value of the loop counter in one of the calling functions)--not what that guy was asking. – Mr.P May 08 '14 at 02:09

1 Answers1

1

Good list of requirements! Of course taking stack trace is not portable but all popular compilers allow to take stack trace. You may start looking at backtrace/backtrace_symbols functions (gcc, clang). Here is an example.

Regarding second point - you'd better limit your exception class with string message. In my experience passing arbitrary information is not really useful (what other handling options do you have except output error message?). If you still insist on linking typed data to exception boost::exception will do the job.

You also may want to add "chained exception" item to your list of requirements. It's useful feature especially when your application has several layers and you rethrow original exception one or more times. C++11 allows to implement chained exception easily. See example of implementation and test cases that show how to use it.

Regarding 4th point - C++ exceptions are not invasive (in a sense). You even don't have to catch it. If you inherit your exception class from std::exception and provide proper implementation of what() the catch side will handle whatever you throw.

AlexT
  • 1,413
  • 11
  • 11
  • Just to clarify: I don't really care about passing typed information, but I want to be able to print state information. e.g. have option to have output like: Exception caught by myFunction on iteration 150. – Mr.P May 08 '14 at 02:17