diff --git a/infer/src/base/Die.ml b/infer/src/base/Die.ml index a7d99eaf4..2acae3d10 100644 --- a/infer/src/base/Die.ml +++ b/infer/src/base/Die.ml @@ -17,14 +17,21 @@ exception InferUserError of string exception InferExit of int -let raise_error error ~msg = +let raise_error ?backtrace error ~msg = + let do_raise exn = + match backtrace with + | None -> + raise exn + | Some backtrace -> + Caml.Printexc.raise_with_backtrace exn backtrace + in match error with | ExternalError -> - raise (InferExternalError msg) + do_raise (InferExternalError msg) | InternalError -> - raise (InferInternalError msg) + do_raise (InferInternalError msg) | UserError -> - raise (InferUserError msg) + do_raise (InferUserError msg) let log_uncaught_exception_callback_ref = ref (fun _ ~exitcode:_ -> ()) diff --git a/infer/src/base/Die.mli b/infer/src/base/Die.mli index 806577772..fee443233 100644 --- a/infer/src/base/Die.mli +++ b/infer/src/base/Die.mli @@ -32,7 +32,7 @@ val log_uncaught_exception : exn -> exitcode:int -> unit val die : error -> ('a, Format.formatter, unit, _) format4 -> 'a (** Raise the corresponding exception. *) -val raise_error : error -> msg:string -> 'a +val raise_error : ?backtrace:Caml.Printexc.raw_backtrace -> error -> msg:string -> 'a type style = Error | Fatal | Normal | Warning diff --git a/infer/src/base/Logging.ml b/infer/src/base/Logging.ml index 82b3753e5..e6dba8359 100644 --- a/infer/src/base/Logging.ml +++ b/infer/src/base/Logging.ml @@ -304,7 +304,12 @@ let log_of_kind error fmt = let die error msg = - F.kasprintf (fun msg -> log_of_kind error "%s@\n" msg ; raise_error error ~msg) msg + let backtrace = Caml.Printexc.get_raw_backtrace () in + F.kasprintf + (fun msg -> + log_of_kind error "%s@\n%s@." msg (Caml.Printexc.raw_backtrace_to_string backtrace) ; + raise_error ~backtrace error ~msg ) + msg (* create new channel from the log file, and dumps the contents of the temporary log buffer there *)