5 ms·
You can have C++ exceptions with a stack trace; you just need to read the relevant debug information. (e.g. DWARF-2 frames). There are libc specific functions t
by daurnimator 11y ago
You can have C++ exceptions with a stack trace; you just need to read the relevant debug information. (e.g. DWARF-2 frames). There are libc specific functions that do this for you. see https://www.gnu.org/software/libc/manual/html_node/Backtraces.html https://www.gnu.org/software/libc/manual/html_node/Backtrace...
Some ffis do this to present C++ stack traces to their host languages.
If variables/frames are optimized out, then yes, you can't display their contents. But anyone that has used gdb already knows this...
- wuch 11y agoLibunwind also works great in this context. For some cases I even found it to work much better than backtrace. It also has a signal-safe functions that facilitate implementation of stack printing on crash. I work with projects where stack traces are added automatically to exceptions during throw. It works quite well, and in fact I would disagree with author on some of his points: - stack trace not representative of source code, due to optimizations - unwinding information is consistent with what you have in a source code, and compiler optimization don't change that (i.e., it would be a compiler bug if it did, see any design document about debugging information, for example in LLVM / Clang). - throw expression is not a place where the problem is - that is of course true in general, but how much more useful is stack trace indicating code path where exception have been thrown, than merely a type of exception. Name of function which have thrown an exception is also a good start, but of limited value for some common utility functions. - memory allocation - dynamic memory allocation could be problematic, but storing stack trace in exception object itself is quite simple and avoid this problem altogether.
- anon4 11y agoThis sort of thing drives me crazy sometimes. Why can't we have a high level assembly language which can represent the code that's executing. Right now I have the choice of either looking at the code, which can be wrong, or looking at assembly, which is hard to associate with the code. Why can't I look at annotated assembly which tells me exactly which part of the code it corresponds to?
- pcwalton 11y ago> Why can't I look at annotated assembly which tells me exactly which part of the code it corresponds to? Because modern optimizations make that impossible. (How do you represent a statement that GVN eliminated, for example?) Not doing those optimizations would make code unacceptably slow.
- pjc50 11y agoUse Visual Studio with optimisation off. Its disassembly view will then line up fairly well with the C++ source. (and with "structured exception handling" and a bit of hacking, you can get backtraces for machine exceptions as well)
- amelius 11y agoBut an issue is still that in the handler (catch clause), the stack has unwound, so if you want to access the stack trace "after the fact", you will have to do some work when throwing the exception.
- barrkel 11y agoYou'd normally use a library that hooks the exception throwing mechanism in the runtime library in a toolset-specific way.
- amelius 11y agoYes, but I mean that every exception will have an additional cost then, because you will have to copy the stack trace (implicitly or explicitly).
- ori_b 11y agoFor many common ABIs, unwinding the stack is relatively cheap compared to decoding the debug info to figure out how to unwind the stack. If you have frame pointers, it's especially cheap -- you're walking a 20 element linked list.