Dan*_*ner 3 ocaml exception stack-trace
我有一个非常短的测试文件:
let print_backtrace () = try raise Not_found with
Not_found -> Printexc.print_backtrace stdout;;
let f () = print_backtrace (); Printf.printf "this is to make f non-tail-recursive\n";;
f ();
Run Code Online (Sandbox Code Playgroud)
我编译并运行:
% ocamlc -g test.ml
% OCAMLRUNPARAM=b ./a.out
Raised at file "test.ml", line 1, characters 35-44
this is to make f non-tail-recursive
Run Code Online (Sandbox Code Playgroud)
为什么没有f列在堆栈跟踪中?如何编写一个函数来打印它所调用位置的堆栈跟踪?
文档Printexc.print_backtrace说:
回溯列出了引发最近引发的异常的程序位置以及通过函数调用传播的位置.
它实际上似乎正在做正确的事情.该异常尚未通过f传播回来.
如果我将呼叫转移到呼叫Printexc.print_backtrace之外f,我会看到完整的回溯.
$ cat test2.ml
let print_backtrace () = raise Not_found
let f () = let res = print_backtrace () in res ;;
try f () with Not_found -> Printexc.print_backtrace stdout
$ /usr/local/ocaml312/bin/ocamlc -g test2.ml
$ OCAMLRUNPARAM=b a.out
Raised at file "test2.ml", line 1, characters 31-40
Called from file "test2.ml", line 3, characters 21-39
Called from file "test2.ml", line 5, characters 4-8
Run Code Online (Sandbox Code Playgroud)
这是执行我建议的代码.如果可能的话,我建议使用ocamldebug,这段代码太棘手了.但是对于这个简单的例子,它适用于我的系统.
let print_backtrace () =
match Unix.fork () with
| 0 -> raise Not_found
| pid -> let _ = Unix.waitpid [] pid in ()
let f () =
begin
print_backtrace ();
Printf.printf "after the backtrace\n";
end
;;
f ()
Run Code Online (Sandbox Code Playgroud)
这是一个测试运行.
$ /usr/local/ocaml312/bin/ocamlc unix.cma -g test3.ml
$ OCAMLRUNPARAM=b a.out
Fatal error: exception Not_found
Raised at file "test3.ml", line 3, characters 17-26
Called from file "test3.ml", line 8, characters 4-22
Called from file "test3.ml", line 14, characters 0-4
after the backtrace
Run Code Online (Sandbox Code Playgroud)
我意识到,由于未被捕获的异常,您实际上无法控制子进程的退出方式.这就是为什么这段代码太棘手了.如果它不适合你,请不要怪我,但我希望它确实有用.
我使用OCaml 3.12.0在Mac OS X 10.6.8上测试了代码.
最好的祝福,
| 归档时间: |
|
| 查看次数: |
1249 次 |
| 最近记录: |