Marc de Kruijf wrote:
Can anyone tell me if invoke/unwind is stable in 2.3? I'm seeing some
really weird stuff -- unwinds are ending up in seemingly arbitrary
definitely not inside the caller's unwind block My target is x86.
As a simple test, I tried to compile the following code and I got a
segmentation fault. It looks good to me. Can someone help me out or is
this a bug?
Marc, I tried the exact same example as you did, and got the same issue.
If you look at the generated x86 machine code, it looks like unwind is
compiled into nothing at all:
.size foo, .-foo
(Note that there isn't even a return instruction). This means your execution
just falls through into the following function without unwinding its own
stack frame. In the above example, this causes it to fall into main and push
another stack frame for main, over and over again until it runs out of stack
space and segfaults.
I can't find any information about cxa_throw at all, not even a type
signature. If I could, could I just call it as if it were unwind, and it
would be caught by invoke?
The function cxa_throw appears to be in libstdc++ in GCC - I can find it in
the object file, but not the source code documentation. Calling it instead
of the LLVM "unwind" instruction seems like an epically nasty hack; totally
undocumented and platform-specific.
Maybe I'm misunderstanding the unwind instruction. The
http://llvm.org/pubs/2004-01-30-CGO-LLVM.pdf 2004 paper describes
exceptions in some detail. They use some front-end specific code for
allocating the exception (eg. __llvm_cxxeh_throw), but then call unwind to
actually unwind the stack.
Are you saying that you need to do something (like call cxa_throw) in*stead*
of calling unwind, or as well as calling unwind? In other words, if LLVM
didn't have this "bug", should Marc's code work fine, or is there still
something else needed?
This discovery is pretty disappointing ... I've been reading the LLVM
documentation for a few days, and everything I've read led me to believe it
had built-in exception handling. If unwind is supposed to work the way Marc
and I are assuming, but in fact just compiles into nothing, then this really
ought to be documented, and the assembler should give a warning or something
if you use it. As it stands, there's no warning that the unwind instruction
is totally being ignored (which is made particularly nasty because it's
recognised as a block terminator, and therefore it allows successful
compilation even when not followed by a ret instruction, where an empty
statement would not).
In the mean time, can anyone suggest a fix for Marc's dummy example which
works in the current version of LLVM (even if it's platform specific)?