diff options
-rw-r--r-- | lib/backtrace.ml | 32 | ||||
-rw-r--r-- | lib/backtrace.mli | 9 | ||||
-rw-r--r-- | lib/errors.ml | 1 |
3 files changed, 24 insertions, 18 deletions
diff --git a/lib/backtrace.ml b/lib/backtrace.ml index 4955437b3..d64f42f7f 100644 --- a/lib/backtrace.ml +++ b/lib/backtrace.ml @@ -26,7 +26,8 @@ type frame = { frame_location : location option; frame_raised : bool; } external get_exception_backtrace: unit -> raw_frame array option = "caml_get_exception_backtrace" -type t = frame list +type t = raw_frame array list +(** List of partial raw stack frames, in reverse order *) let empty = [] @@ -42,15 +43,21 @@ let of_raw = function } in { frame_location = Some loc; frame_raised = r; } -let push stack = match get_exception_backtrace () with -| None -> [] -| Some frames -> - let len = Array.length frames in +let rec repr_aux accu = function +| [] -> accu +| fragment :: stack -> + let len = Array.length fragment in let rec append accu i = if i = len then accu - else append (of_raw frames.(i) :: accu) (succ i) + else append (of_raw fragment.(i) :: accu) (succ i) in - append stack 0 + repr_aux (append accu 0) stack + +let repr bt = repr_aux [] (List.rev bt) + +let push stack = match get_exception_backtrace () with +| None -> [] +| Some frames -> frames :: stack (** Utilities *) @@ -80,17 +87,12 @@ let add_backtrace e = let current = get_exception_backtrace () in begin match current with | None -> e - | Some frames -> - let len = Array.length frames in - let rec append accu i = - if i = len then accu - else append (of_raw frames.(i) :: accu) (succ i) - in - let old = match get_backtrace e with + | Some fragment -> + let bt = match get_backtrace e with | None -> [] | Some bt -> bt in - let bt = append old 0 in + let bt = fragment :: bt in Exninfo.add e backtrace bt end else e diff --git a/lib/backtrace.mli b/lib/backtrace.mli index d5a96e6f7..b5a956573 100644 --- a/lib/backtrace.mli +++ b/lib/backtrace.mli @@ -32,9 +32,8 @@ type frame = { frame_location : location option; frame_raised : bool; } (** A frame contains two informations: its optional physical location, and whether it raised the exception or let it pass through. *) -type t = frame list -(** Type of backtraces. They're just stack of frames. [None] indicates that we - don't care about recording the backtraces. *) +type t +(** Type of backtraces. They're essentially stack of frames. *) val empty : t (** Empty frame stack. *) @@ -42,6 +41,10 @@ val empty : t val push : t -> t (** Add the current backtrace information to a given backtrace. *) +val repr : t -> frame list +(** Represent a backtrace as a list of frames. Leftmost element is the outermost + call. *) + (** {5 Utilities} *) val print_frame : frame -> string diff --git a/lib/errors.ml b/lib/errors.ml index 75464f2da..157949fcd 100644 --- a/lib/errors.ml +++ b/lib/errors.ml @@ -88,6 +88,7 @@ let print_anomaly askreport e = let bt_info = match Backtrace.get_backtrace e with | None -> mt () | Some bt -> + let bt = Backtrace.repr bt in let pr_frame f = str (Backtrace.print_frame f) in let bt = prlist_with_sep fnl pr_frame bt in fnl () ++ hov 0 bt |