Printing stack traces

感情迁移 提交于 2019-12-20 02:18:06

问题


I have a very short test file:

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 ();

I compile and run:

% 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

Why isn't f listed in the stack trace? How can I write a function that will print a stack trace of the location it's called from?


回答1:


Here is the code to do what I suggested. I recommend using ocamldebug if at all possible, this code is much too tricky. But it works on my system for this simple example.

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 ()

Here is a test run.

$ /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

I realized that because of the uncaught exception, you don't really have any control over the way the child process exits. That's one reason this code is much too tricky. Please don't blame me if it doesn't work for you, but I hope it does prove useful.

I tested the code on Mac OS X 10.6.8 using OCaml 3.12.0.

Best regards,




回答2:


The documentation for Printexc.print_backtrace says:

The backtrace lists the program locations where the most-recently raised exception was raised and where it was propagated through function calls.

It actually seems to be doing the right thing. The exception hasn't been propagated back through f.

If I move the call to Printexc.print_backtrace outside the call to f, I see a full backtrace.

$ 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


来源:https://stackoverflow.com/questions/7599472/printing-stack-traces

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!