LDC compiler gives garbage instead of stack trace when exceptions are thrown
Closed this issue · 3 comments
By default the LDC compiler doesn't include the symbols needed for a nice stack trace, even when compiling with -g
Example:
core.exception.RangeError@sfluidblock.d(2689): Range violation
----------------
??:? [0x5567cb998a25]
??:? [0x5567cb9c257e]
??:? [0x5567cb9a3ddd]
??:? [0x5567cb9980f8]
??:? [0x5567cb9987e7]
??:? [0x5567cb712f8e]
??:? [0x5567cb7169e0]
??:? [0x5567cb914532]
??:? [0x5567cb7bac66]
??:? [0x5567cb7967ae]
??:? [0x5567cb735cc5]
??:? [0x5567cb901fde]
??:? [0x5567cb92617f]
??:? [0x5567cb9a3a5f]
??:? [0x5567cb9a3952]
??:? [0x5567cb9a37ad]
??:? [0x5567cb926684]
??:? __libc_start_main [0x7f829e299082]
??:? [0x5567cb25c5ad]
This LDC issue (ldc-developers/ldc#863) explains that adding -L-export-dynamic to the compile returns the expected output, which it does:
core.exception.RangeError@sfluidblock.d(2689): Range violation
----------------
??:? @nogc void sfluidblock.SFluidBlock.first_order_flux_calc(ulong) [0x5604b1957b53]
??:? @nogc void sfluidblock.SFluidBlock.convective_flux_phase0(bool, ulong) [0x5604b195bbe0]
??:? int steadystate_core.evalRHS(double, int).__foreachbody5(ref fluidblock.FluidBlock) [0x5604b1bce812]
??:? int std.parallelism.doSizeZeroCase!(fluidblock.FluidBlock[], int delegate(ref fluidblock.FluidBlock)).doSizeZeroCase(ref std.parallelism.ParallelForeach!(fluidblock.FluidBlock[]).ParallelForeach, int delegate(ref fluidblock.FluidBlock)) [0x5604b1a36ba6]
??:? int std.parallelism.ParallelForeach!(fluidblock.FluidBlock[]).ParallelForeach.opApply(scope int delegate(ref fluidblock.FluidBlock)) [0x5604b19ec69e]
??:? void steadystate_core.evalRHS(double, int) [0x5604b197b015]
??:? void steadystate_core.iterate_to_steady_state(int, int, int, bool, bool) [0x5604b1bbc15e]
??:? _Dmain [0x5604b1be2a4f]
The stated reason for this is that the option increases the size of the executable (it's off by default), but I have found that this only changes the size of e4-nk-shared from 18M to 25M. If there's no performance penalty for doing so, I propose including -L-export-dynamic in the debug flavour of the code.
Test results with commit 8b5e6e2, using the example code in examples/eilmer/2D/flat-plate-turbulent-mabey/su2-steady-state-solver, compiled with debug mode and run with a single thread:
Execution speed (three trials):
$ time e4-nk-shared --job=mabey --verbosity=1 --max-cpus=1
With -L-export-dynamic -link-defaultlib-debug
real 0m38.405s, 0m38.386s, 0m38.046s
Without (reference commit 8b5e6e24)
real 0m36.413s, 0m37.048s, 0m37.270s
File sizes:
WITH WITHOUT
e4mpi* 28M 17M
e4-nk-dist* 30M 19M
e4-nk-dist-real* 29M 17M
e4-nk-shared* 30M 18M
e4-nk-shared-real* 29M 17M
e4shared* 28M 17M
e4zmpi* 30M 18M
e4zshared* 30M 18M
Note that the above stack trace does not have line numbers/filenames in it. This is because of a bug in older ldc2 compilers:
compile v1.24 and 1.28:
object.Error@(0): RIP
----------------
??:? @nogc void ufluidblock.UFluidBlock.convective_flux_phase2(bool, ulong, fvcell.FVCell[], fvinterface.FVInterface[], fvvertex.FVVertex[]) [0x562ca66d6ad4]
Compile with v1.32:
object.Error@(0): RIP
----------------
ufluidblock.d:887 @nogc void ufluidblock.UFluidBlock.convective_flux_phase2(bool, ulong, fvcell.FVCell[], fvinterface.FVInterface[], fvvertex.FVVertex[]) [0x564391322942]
A workaround for older compilers is to use the full path:
$ /home/uqngibbo/programs/gdtk/bin/e4-nk-shared --job=mabey --verbosity=1 --max-cpus=1
object.Error@(0): RIP
----------------
/home/uqngibbo/source/gdtk.fresh/src/eilmer/ufluidblock.d:887 @nogc void ufluidblock.UFluidBlock.convective_flux_phase2(bool, ulong, fvcell.FVCell[], fvinterface.FVInterface[], fvvertex.FVVertex[]) [0x559d54b31ad4]