aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/backtrace.ml32
-rw-r--r--lib/backtrace.mli9
-rw-r--r--lib/errors.ml1
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