2014-02-06 53 views

回答

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 

感謝丹尼爾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 
+2

應該補充說,如果編譯爲字節碼,堆棧跟蹤會更加精確。 –

+2

您也可以使用'Printexc.record_backtrace true'來避免設置shell環境變量的麻煩,例如一行'if if debug then Printexc.record_backtrace true;'somewhere;和ocamlbuild的'ocamlbuild X.d.byte'目標,這是可以肯定的。 – lukstafi

+0

@lukstafi,這是非常有用的,特別是當使用ocamlbuild構建項目時。 – computereasy