Assert failure does not print full stack trace

Hello all,

It seems when assertion failure is hit a portion of stack trace is optimized away.

ubuntu:~/ocaml-playground$ dune test                            
File "lib/Instr.ml", line 137, characters 2-71: <<true>> threw "Assert_failure lib/Util.ml:97:2".
  Raised at file "src/exn.ml", line 71, characters 4-114                                         
  Called from file "runtime-lib/runtime.ml", line 356, characters 15-52                          
  Called from file "runtime-lib/runtime.ml", line 444, characters 52-83                          
  in TEST_MODULE at file "lib/intro.ml", line 136, characters 0-110                              

The printed stack trace misses a few function calls.

Is there a way to fully print it?

Thanks!

Missing stack frames can be due to various causes. It’s hard to pin the right one without seeing your code, but here are a few possible reasons:

  • catching an exception using try...with and then raising that exception again erases the first backtrace;
  • if a function ends in a tail call, its stack frame is reused and thus it will not appear in the stack trace;
  • C functions in general do not appear in OCaml backtraces.

To see a more complete backtrace, you can use a debugger, insert a breakpoint at the location of your assertion, and when it is reached fails, ask a backtrace from the debugger.

This is not always so. The compiler tries to detect when an exception is re-raised in an exception handler and it will preserve the stack trace in that case. But the heuristics are not perfect so it won’t work every time. On the other hand, it is possible to always preserve the existing backtrace by declaring

external reraise : exn -> 'a = "%reraise"

and using it to re-throw an exception in an exception handler. See also Printexc.reraise_with_backtrace.

Cheers,
Nicolas

3 Likes

I no longer remembered about these techniques. Thanks!

Thank you all for comments! The reason was an infinitely recursive call. I could catch this by opening dune utop and rerunning the problematic unit test, which finally printed the full stack trace. :slight_smile: