Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] getting stack traces in running code
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Issac Trotts <ijtrotts@n...>
Subject: Re: [Caml-list] getting stack traces in running code
On Tue, Dec 02, 2003 at 03:50:40PM -0500, Yaron M. Minsky wrote:
> Is there a reason why stack traces are available only on a crash?  I
> have a project (a distributed OpenPGP keyserver system,
> http://www.nongnu.org/sks/) that is a long-running daemon.  Unexpected
> errors are caught and logged, but unfortunately, there's no way of
> getting a stack-trace, since I don't let the exceptions kill the
> program.  This makes debugging much more difficult, and is one of the
> single largest difficulties I have with ocaml.  Is there a technical
> reason that a bytecode-compiled executable couldn't have access to the
> stack trace during execution?

I have a partial solution:

ijtrotts@manzanita:~/tmp/backtrace$ cat backtrace.ml
 
external internal_print : exn -> unit
        = "camlidl_bt_print_exception_backtrace"
 
let print exc =
  prerr_endline (Printexc.to_string exc);
  internal_print exc;
 
ijtrotts@manzanita:~/tmp/backtrace$ cat backtrace.mli
val print : exn -> unit
 
ijtrotts@manzanita:~/tmp/backtrace$ cat bt_stubs.c
/* File generated from bt.idl */
 
#include <stddef.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/fail.h>
#include <caml/callback.h>
#ifdef Custom_tag
#include <caml/custom.h>
#include <caml/bigarray.h>
#endif
 
#include <stdio.h>
 
void print_exception_backtrace(void);
 
value camlidl_bt_print_exception_backtrace(value exn)
{
  print_exception_backtrace();
  return Val_unit;
}
 
ijtrotts@manzanita:~/tmp/backtrace$ cat test_bt.ml
let quux() = raise (Failure "quux has failed")
 
let baz() = quux()
 
let bar() = baz()
 
let foo() = bar()
 
let () =
  let rec loop = function
      0 -> ()
    | k ->
      begin try foo() with Failure _ as e -> Backtrace.print e end;
      print_newline();
      loop(k-1) in
  loop 3
 
ijtrotts@manzanita:~/tmp/backtrace$ cat Makefile
test_bt: test_bt.ml backtrace.mli backtrace.ml bt_stubs.o
        ocamlc -custom -g -o test_bt bt_stubs.o backtrace.mli backtrace.ml \
          test_bt.ml
 
bt_stubs.o: bt_stubs.c
        ocamlc -c $<
 
It's not quite right yet because it only prints out the 
place where the exception was raised (which will be in 
Pervasives if you use failwith), and the place where it 
was caught and printed.  Does someone know how to make it
print the whole stack?

-- 
Issac Trotts

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners