First of all a preface - This problem was spotted while trying to
build a large C++ project which links a close to 100 of object file
together, plus libraries. I can't replicate this behavior in a simple
isolated test. Just want to understand if potentially this may be
caused by clang's compiler or linker behavior (missed flag, or
optimization effect/bug). The project builds and runs correctly with
Compiler: clang-10 on OSX 10.13
The project builds fully without errors and the final binary
executable is produced. The binary starts up ok and presents a prompt.
However any exception-based processing (like input errors are expected
to show a message and continue, or catching Ctrl+C and processing into
a message and continue) result in uncaught exception and ends in
abort(). Basically, the libc++ calls std::terminate(), as if the
proper catch statement is missing, which clearly is in the code.
Somehow the exception unwind stack gets broken.
The code links a large number of objects and a few .a libraries, so I
tried to put the individual objects into another .a lib to try to
eliminate the order effects. Still, the resulting binary has the
exception catching issues.
Then I tried to craft a simple test (which does not use any of the
actual project's code) that has throw/catch and then linked it in the
same way. The results:
* when the test code is linked from the .a library (with all objects
as above), the exceptions are processed ok.
* when the test code is linked with all the objects above specified
on the command line, the exception issues are back.
Obviously, the simple test code does not need any of the code from the
other objects, yet the resulting code appears somehow broken. Granted,
the linker will have to resolve all dependecies it finds on the
command line and tie it into the binary, still none of those functions
should be executed by the sample test code.
Finally, I tried to change the order of the project's object files at
line and put the object file which does the actual throw, right next
to the main's object file. To my surprise, the exceptions were caught
ok... But too soon to celebrate, exceptions tripped in other parts of
the code still were not caught properly.
So the bottom line, some how the exceptions table gets messed up in
the process on linking. I can't think of any other way to diagnose
By the way, the very same code is properly linked and functioning when
using GCC default compile/link options.
I tired without success -fno-lto to disable link-time-optimization,
but that's default anyway.
To reiterate the questions:
1. Why would order of the object files matter for correct exception processing?
2. Are there some clang's options specific for such cases?
Any ideas are welcome!