I am working on a reasonable large Dlang program that links to C and Fortran libraries. With recent updates on macOS, I was having trouble linking to the Fortran libraries but found the -L-no_compact_unwind allowed me to get a build going, so long as I also had the optimisation flag -O set. If I omitted the optimisation flag, the program would no longer catch exceptions.
I have made a small example of this behaviour below. The transcript shows first the program built with optimisation on and catching the exception. The second part shows the build without optimisation failing to catch the exception.
Am I just using the compiler incorrectly or is there a bug?
peterj@mini test-exception % ./run_test_exception.sh
Compile code
Run without throwing an exception
Success: mf=1
mf=1
Run and cause the throwing of an exception that should be caught
Caught expection message: oops
mf=2
peterj@mini test-exception % nvim run_test_exception.sh
peterj@mini test-exception % ./run_test_exception.sh
Compile code
Run without throwing an exception
Success: mf=1
mf=1
Run and cause the throwing of an exception that should be caught
rt/dwarfeh.d:369: uncaught exception reached top of stack
This might happen if you're missing a top level catch in your fiber or signal handler
test_exception.MyException@test_exception.d(17): oops
----------------
??:? object.Throwable.TraceInfo core.runtime.defaultTraceHandler(void*) [0x1047e2283]
??:? _Dmain [0x10478507b]
./run_test_exception.sh: line 9: 1155 Abort trap: 6 ./test_exception fail
peterj@mini test-exception %
# run_test_exception.sh
echo "Compile code"
# ldc2 -O -L-no_compact_unwind test_exception.d
ldc2 -L-no_compact_unwind test_exception.d
# ldc2 test_exception.d
echo "Run without throwing an exception"
./test_exception ok
echo "Run and cause the throwing of an exception that should be caught"
./test_exception fail
// test_exception.d
import std.stdio;
class MyException : Exception {
@nogc
this(string message, string file=__FILE__, size_t line=__LINE__,
Throwable next=null)
{
super(message, file, line, next);
}
}
string get_stuff(string incoming) {
string outgoing = "stuff";
if (incoming == "fail") {
throw new MyException("oops");
}
return outgoing;
}
int main(string[] args)
{
double mf = 0.0;
try {
mf = 1.0;
string txt = get_stuff(args[1]);
writefln("Success: mf=%g", mf);
} catch (MyException e) {
writefln("Caught expection message: %s", e.msg);
mf = 2.0;
}
writefln("mf=%g", mf);
return 0;
}
peterj@mini test-exception % ldc2 --version
LDC - the LLVM D compiler (1.38.0):
based on DMD v2.108.1 and LLVM 18.1.5
built with LDC - the LLVM D compiler (1.38.0)
Default target: arm64-apple-darwin23.5.0
Host CPU: apple-m1
http://dlang.org - http://wiki.dlang.org/LDC