27066


OCamlでexn型の値からスタックトレースを取得する方法はありますでしょうか？JavaのgetStackTrace()のような。

標準のPrintexcモジュールを探したのですが、現在のスタックトレースを取得する Printexc.get_backtrace
はあるものの、例外からこしらえる方法が分かりませんでした。

参考: <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printexc.html>

例えば次のようなプログラムで、work関数が失敗したときのスタックトレースを処理したいことなどがあります。

[code]

    open Batteries
    
    let work () = ...
    
    let _ =
      match wrap work () with
      | Ok result -> print_endline result
      | Bad e ->
         (* ここでスタックトレースも出力したい *)
         prerr_endline (Printexc.to_string e);
         exit 1
    
[/code]

コマンドラインのシステムなら単純にraiseで例外を投げてしまうのもアリかもしれませんが、ログファイルに保存したり、DBに保存したりしたいこともあると思うのです。


CC BY-SA 3.0
2016-06-24T12:08:28.437
27030
2016-06-25T14:14:46.580
16929
question
ocaml exception
OCamlで例外からスタックトレースを取得する方法


OCaml 4.03.0, batteries.2.5.2 で次のプログラムを環境変数 `OCAMLRUNPARAM` に `b`
を設定するとバックトレースは出力されます:

[code]

    (* with export OCAMLRUNPARAM=b *)
    (* ocamlfind ocamlopt -package batteries -linkpkg -o z.exe z.ml *)
    open Batteries
    
    let work () = 
      let rec f = function
        | 0 -> raise Exit
        | n -> f (n-1) ^ "x"
      in
      f 10
    
    let _ =
      match wrap work () with
      | Ok result -> print_endline result
      | Bad e ->
         prerr_endline @@ Printexc.get_backtrace ();
         prerr_endline @@ Printexc.to_string e;
         exit 1
    
[/code]

以下が私の環境での出力です:

[code]

    Raised at file "z.ml", line 5, characters 21-25
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "z.ml", line 6, characters 15-22
    Called from file "src/batInnerPervasives.mlv", line 59, characters 22-27
    
    Pervasives.Exit
    
[/code]

質問者の環境でなぜトレースが出力されないのかわかりませんが、一般的には環境変数 `OCAMLRUNPARAM` を設定していない事が多いです。

なお、`get_backtrace` や `print_backtrace`
は最後の例外発生時のスタックトレースを得るものです。「現在のスタックトレース」をとるものではありません。また、例外自体はスタックトレースを持っていません。


CC BY-SA 3.0
2016-06-25T12:14:03.947
27066
2016-06-25T14:14:46.580
2016-06-25T14:14:46.580
898
898
27030
answer