Clément
Clément

Reputation: 12927

How can I get a complete, untrucated stack trace in OCaml after a stack overflow?

OCaml stack traces for stack overflows are truncated; for example, the following program produces the stack trace shown below:

let rec f0 () = 1 + f1 ()
    and f1 () = 1 + f2 ()
    and f2 () = 1 + f3 ()
    and f3 () = 1 + f4 ()
    and f4 () = 1 + f5 ()
    and f5 () = 1 + f5 ()

let _ =
  Printexc.record_backtrace true;
  f0 ()

Fatal error: exception Stack overflow
Raised by primitive operation at file "stackoverflow.ml", line 6, characters 20-25
Called from file "stackoverflow.ml", line 6, characters 20-25
…
Called from file "stackoverflow.ml", line 6, characters 20-25

Contrast with the stack trace when the error is not a stack overflow (change the final f5 () into failwith "Oops":

Fatal error: exception Failure("Oops")
Raised at file "pervasives.ml", line 30, characters 22-33
Called from file "stackoverflow.ml", line 6, characters 20-35
Called from file "stackoverflow.ml", line 5, characters 20-25
Called from file "stackoverflow.ml", line 4, characters 20-25
Called from file "stackoverflow.ml", line 3, characters 20-25
Called from file "stackoverflow.ml", line 2, characters 20-25
Called from file "stackoverflow.ml", line 1, characters 20-25
Called from file "stackoverflow.ml", line 10, characters 2-7

How can I prevent OCaml from truncating stack traces?

Upvotes: 5

Views: 957

Answers (3)

bthom
bthom

Reputation: 36

You can use ocamldebug to get the stack trace:

ocamlc stackoverflow.ml -o stackoverflow
ocamldebug stackoverflow

then in ocamldebug :

(ocd) run
 [...] 
 Uncaught exception: Stack_overflow
(ocd) backstep
(ocd) bt

You may want to add the debug flag to ocamlc (-g) to do extra things in the debugger.

Upvotes: 2

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66793

When I reproduce your results I get 1024 lines of backtrace, which is a suspicious number.

In fact, I see that the library imposes a hard-coded maximum backtrace size of 1024 in byterun/caml/backtrace_prim.h:

#define BACKTRACE_BUFFER_SIZE 1024

You might have to build a new standard library if you want larger backtraces.

For what it's worth I did a little test with ocamlc and I see around 262,000 active stack frames when the overflow occurs (with default stack size).

(Edited with correct filename for OCaml 4.04.)

Upvotes: 4

Thomas Leonard
Thomas Leonard

Reputation: 7196

You could limit the stack so it doesn't overflow the backtrace buffer, e.g. (tested with bytecode)

$ env OCAMLRUNPARAM=b,l=1000 ./test
[...]
Called from file "test.ml", line 6, characters 20-25
Called from file "test.ml", line 6, characters 20-25
Called from file "test.ml", line 5, characters 20-25
Called from file "test.ml", line 4, characters 20-25
Called from file "test.ml", line 3, characters 20-25
Called from file "test.ml", line 2, characters 20-25
Called from file "test.ml", line 1, characters 20-25
Called from file "test.ml", line 10, characters 2-7

Upvotes: 2

Related Questions