我可以让OCaml在未捕获的异常上产生堆栈跟踪吗?

bro*_*s94 2 ocaml

在Java中,当异常转义main()函数时,会向控制台打印堆栈跟踪.你能让OCaml程序做同样的事情吗?

Jef*_*eld 5

是的,用-g编译并设置 OCAMLRUNPARM=b

$ cat exc.ml
let f () : int =
    raise End_of_file

let g () =
    f () + 44

let _ = g()
$ ocamlc -g -o exc exc.ml
$ OCAMLRUNPARAM=b exc
Fatal error: exception End_of_file
Raised at file "exc.ml", line 2, characters 10-21
Called from file "exc.ml", line 5, characters 4-8
Called from file "exc.ml", line 7, characters 8-11
Run Code Online (Sandbox Code Playgroud)

感谢DanielBünzli指出如果编译为本机代码,行为可能会有所不同.这是我在我的系统上看到的内容(Mac OS X 10.9.1,OCaml 4.01.0):

$ ocamlopt -g -o exc exc.ml
$ OCAMLRUNPARAM=b exc
Fatal error: exception End_of_file
Raised by primitive operation at file "exc.ml", line 5, characters 4-8
Called from file "exc.ml", line 7, characters 8-11
Run Code Online (Sandbox Code Playgroud)

如果你关闭内联,事情似乎工作得很好(至少对于这个非常简单的例子):

$ ocamlopt -inline 0 -g -o exc exc.ml
$ OCAMLRUNPARAM=b exc
Fatal error: exception End_of_file
Raised at file "exc.ml", line 2, characters 10-21
Called from file "exc.ml", line 5, characters 4-8
Called from file "exc.ml", line 7, characters 8-11
Run Code Online (Sandbox Code Playgroud)

  • 应该补充一点,如果编译为字节码,堆栈跟踪往往会更精确. (2认同)
  • 您还可以使用`Printexc.record_backtrace true`来避免设置shell环境变量的麻烦,例如一行`if!debug然后Printexc.record_backtrace true;`somewhere; 和ocamlbuild Xdbyte`目标为ocamlbuild,只是为了确定. (2认同)