2
在Java中,當一個異常轉義main()函數時,stacktrace被打印到控制檯。你可以讓OCaml程序做同樣的事情嗎?我可以讓OCaml在未捕獲的異常上產生堆棧跟蹤嗎?
在Java中,當一個異常轉義main()函數時,stacktrace被打印到控制檯。你可以讓OCaml程序做同樣的事情嗎?我可以讓OCaml在未捕獲的異常上產生堆棧跟蹤嗎?
是,編譯-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
感謝丹尼爾Bü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
如果關閉內聯,事情似乎工作得很好(至少在這個非常簡單的例子):
$ 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
應該補充說,如果編譯爲字節碼,堆棧跟蹤會更加精確。 –
您也可以使用'Printexc.record_backtrace true'來避免設置shell環境變量的麻煩,例如一行'if if debug then Printexc.record_backtrace true;'somewhere;和ocamlbuild的'ocamlbuild X.d.byte'目標,這是可以肯定的。 – lukstafi
@lukstafi,這是非常有用的,特別是當使用ocamlbuild構建項目時。 – computereasy