
Why you cannot have C++ exceptions with a stack trace - ingve
http://www.di.unipi.it/~nids/docs/i_want_my_pony_or_why_you_cannot_have_cpp_exceptions_with_a_stack_trace.html
======
daurnimator
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/Backtrace...](https://www.gnu.org/software/libc/manual/html_node/Backtraces.html)

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...

~~~
anon4
This 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
> 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.

------
js2
_To recap, if you want to implement your own exceptions in C++ with the stack
trace in the same way as Java or C# do, that 's good fun._

Just use Google Breakpad. For Objective-C, you'll probably do better with
PLCrashReporter (or possibly KSCrash) which can reliably unwind at the time of
the crash because of certain assumptions it can make about ObjC binaries that
the more general Breakpad does not make. (Breakpad just captures the stacks to
a minidump, which you then unwind later using symbol files generated from your
binaries.)

 _you usually need to allocate a piece of memory in the heap_

Breakpad preallocates. The ObjC (Mac, iOS) handler included with Breakpad
(should you go that route) goes so far as to mprotect the preallocated memory
to help protect it from memory smashers.

None of this is perfect, but I'd rather have stack traces than not. It's also
useful to have a breadcrumb mechanism in the app to include with the stack
trace.

------
ggambetta
Back in 2001, when VS6 couldn't even parse templates correctly, I was making
games on Linux but wanted them to run on Windows and Mac too.

I also wanted stack traces in exceptions (or being able to get them at any
time, really) and I wanted to make them encrypted, to avoid giving away the
internal structure of our game and engine code.

The solution I came up with was to have a global array representing the stack
trace, a macro that would create a small scoped object which pushed a new
"stack trace" entry on creation and popped it on destruction, and a script
that would add a call to this macro to the beginning of each method with any
payload I wanted -usually the encrypted filename, line and signature of the
method, but it was possible to append e.g. parameter values as well.

Since these strings were compile time constants, this whole thing was
surprisingly cheap, and worked great for over a decade.

With C++ there _always_ is a way :)

------
unfamiliar
Most of the reasoning here seems to be based on 1) that "out of memory" is the
only exception worth talking about, and 2) the only thing you want to do is
abort the program at that point.

I don't think either of these are true. Some libraries make liberal use of
exceptions, as a design decision. If your text editor tries to open an
enormous file, you don't want it to crash, you want it to deallocate all of
the memory it consumed for that file and then fall back with an error message.

I don't think the point about inlining is reasonable either: I wouldn't expect
a fully optimised build to give me a full stack trace, that is what debug
builds are for.

>If the exception is meant to signal the fact that the memory is finished,
where are we allocating the stack trace?

If this is really a concern, allocate some memory at the start of execution
that you can use in the event of a crash.

~~~
joosters
Unless you have carefully configured your OS, 'out of memory' exceptions are
essentially worthless. This is because most systems work using 'optimistic'
memory management, where it is not known (or checked) whether there is enough
free memory available at the time of the malloc() call. The problem comes
later, at any time when a random instruction tries to access the memory and
the OS finds that it has no RAM available.

------
Negitivefrags
On Windows, C++ exceptions have a stack trace.

It's not perfect because all the destructors for your stack allocated objects
have run. So for example, any std::string on the stack will be gone, but any
pointers to structures on the heap are still intact.

In addition, just knowing what the stack was is invaluable in debugging even
if you don't have the values of every variable.

It's a huge pain that you can't get that under linux.

------
alexnewman
[http://phildawes.net/blog/2015/06/17/rust-
stacktrace/](http://phildawes.net/blog/2015/06/17/rust-stacktrace/)

------
stinos
Like the article, but I'm really not digging that style used for inline code
snippets. Just changing font face and color a bit seems like a proven solution
to me. Doing that but also adding ⌈characters⌋ around it makes it hard to
read. At least for me.

~~~
pmontra
Same feelings here: nice post but bad typography. To the author and anybody
writing their own CSS: please use line spacing to make it easier to get the
starting point of the next long line of text. See
[https://www.w3.org/TR/WCAG20-TECHS/C21.html](https://www.w3.org/TR/WCAG20-TECHS/C21.html)
and, believe me, it doesn't impact only "people with cognitive disabilities".

------
makecheck
There are functions that can capture or print stack traces, such as the
backtrace() family on OS X (which has a "man" page) or just the "pstack"
command on Linux. It is very useful to have a function in your code base that
invokes one of these on demand.

Then you can do interesting things like print a stack trace at a "throw" point
if you suspect a problem, or capture a trace into an exception base class in
debug modes for printing at catch points, or even as a form of non-crashing
assertion to log traces whenever unexpected conditions arise.

------
dfox
It's true that exceptions in C++ are more expensive than in other languages,
often even in absolute terms, but that has nothing to do with problem at hand.

In GC'd language, implementing exceptions by simple non-local exit to
catch/finally block is perfectly viable implementation strategy. It does not
work so well in C++, where are implicit finally blocks that call destructors
of local variables almost everywhere. To some extent this feature could be
abused to produce stack-trace during the unwinding (but that necessarily
involves injecting code to all functions in the program).

On the other hand, CL/Smalltalk-style condition systems sidestep this issue
completely, by running the handler code before unwinding the stack. Windows'
SEH allows you to do the same thing. And IIRC even in plain C++, handler for
completely unhandled exception (that by default involves call to abort()) runs
without stack unwinding (thus something along the lines of std::set_terminate
(__gnu_cxx::__verbose_terminate_handler) gives you stacktraces for unhandled
exceptions).

------
ori_b
I'd rather have a core dump than a stack trace. There's so much more
information in a core dump. The stack is there as well, but having all live
variables in the program, all loaded code, and all process state makes it so
much easier to debug what's going wrong.

~~~
pjmlp
I rather have both.

------
halayli
And what's wrong with using libunwind?

