You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
7.4 KiB
246 lines
7.4 KiB
(*
|
|
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
|
* Copyright (c) 2013 - present Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*)
|
|
|
|
open! Utils
|
|
|
|
(** log messages at different levels of verbosity *)
|
|
|
|
module F = Format
|
|
|
|
(** type of printable elements *)
|
|
type print_type =
|
|
| PTatom
|
|
| PTdecrease_indent
|
|
| PTexp
|
|
| PTexp_list
|
|
| PThpred
|
|
| PTincrease_indent
|
|
| PTinstr
|
|
| PTinstr_list
|
|
| PTjprop_list
|
|
| PTjprop_short
|
|
| PTloc
|
|
| PTnode_instrs
|
|
| PToff
|
|
| PToff_list
|
|
| PTpath
|
|
| PTprop
|
|
| PTproplist
|
|
| PTprop_list_with_typ
|
|
| PTprop_with_typ
|
|
| PTpvar
|
|
| PTspec
|
|
| PTstr
|
|
| PTstr_color
|
|
| PTstrln
|
|
| PTstrln_color
|
|
| PTpathset
|
|
| PTpi
|
|
| PTsexp
|
|
| PTsexp_list
|
|
| PTsigma
|
|
| PTtexp_full
|
|
| PTsub
|
|
| PTtyp_full
|
|
| PTtyp_list
|
|
| PTwarning
|
|
| PTerror
|
|
| PTinfo
|
|
|
|
(** delayable print action *)
|
|
type print_action =
|
|
print_type * Obj.t (** data to be printed *)
|
|
|
|
let delayed_actions = ref []
|
|
|
|
(** hook for the current printer of delayed print actions *)
|
|
let printer_hook = ref (Obj.magic ())
|
|
|
|
let out_formatter, err_formatter =
|
|
(** Create a directory if it does not exist already. *)
|
|
(* This is the same as DB.create_dir, except for logging to stderr *)
|
|
let create_dir dir =
|
|
try
|
|
if (Unix.stat dir).Unix.st_kind != Unix.S_DIR then
|
|
failwithf "@.ERROR: file %s exists and is not a directory@." dir
|
|
with Unix.Unix_error _ ->
|
|
try Unix.mkdir dir 0o700
|
|
with Unix.Unix_error _ ->
|
|
let created_concurrently = (* check if another process created it meanwhile *)
|
|
(Unix.stat dir).Unix.st_kind = Unix.S_DIR in
|
|
if not created_concurrently then
|
|
failwithf "@.ERROR: cannot create directory %s@." dir
|
|
in
|
|
let open_output_file fname =
|
|
try
|
|
let cout = open_out fname in
|
|
let fmt = F.formatter_of_out_channel cout in
|
|
(fmt, cout)
|
|
with Sys_error _ ->
|
|
failwithf "@.ERROR: cannot open output file %s@." fname
|
|
in
|
|
if Config.developer_mode
|
|
&& Sys.file_exists Config.results_dir
|
|
&& Sys.is_directory Config.results_dir
|
|
then
|
|
let log_dir_name = "log" in
|
|
let analyzer_out_name = "analyzer_out" in
|
|
let analyzer_err_name = "analyzer_err" in
|
|
let log_dir = Filename.concat Config.results_dir log_dir_name in
|
|
create_dir log_dir;
|
|
let analyzer_out_file =
|
|
if Config.out_file_cmdline = "" then Filename.concat log_dir analyzer_out_name
|
|
else Config.out_file_cmdline in
|
|
let analyzer_err_file =
|
|
if Config.err_file_cmdline = "" then Filename.concat log_dir analyzer_err_name
|
|
else Config.err_file_cmdline in
|
|
let out_fmt, out_chan = open_output_file analyzer_out_file in
|
|
let err_fmt, err_chan = open_output_file analyzer_err_file in
|
|
Pervasives.at_exit (fun () ->
|
|
F.pp_print_flush out_fmt () ;
|
|
F.pp_print_flush err_fmt () ;
|
|
close_out out_chan ;
|
|
close_out err_chan
|
|
);
|
|
(out_fmt, err_fmt)
|
|
else
|
|
(F.std_formatter, F.err_formatter)
|
|
|
|
(** extend the current print log *)
|
|
let add_print_action pact =
|
|
if Config.write_html then delayed_actions := pact :: !delayed_actions
|
|
else if not Config.test then !printer_hook out_formatter pact
|
|
|
|
(** reset the delayed print actions *)
|
|
let reset_delayed_prints () =
|
|
delayed_actions := []
|
|
|
|
(** return the delayed print actions *)
|
|
let get_delayed_prints () =
|
|
!delayed_actions
|
|
|
|
(** set the delayed print actions *)
|
|
let set_delayed_prints new_delayed_actions =
|
|
delayed_actions := new_delayed_actions
|
|
|
|
let do_print fmt fmt_string =
|
|
F.fprintf fmt fmt_string
|
|
|
|
let do_print_in_developer_mode fmt fmt_string =
|
|
if Config.developer_mode then
|
|
F.fprintf fmt fmt_string
|
|
else
|
|
F.ifprintf fmt fmt_string
|
|
|
|
(** print to the current out stream (note: only prints in developer mode) *)
|
|
let out fmt_string =
|
|
do_print_in_developer_mode out_formatter fmt_string
|
|
|
|
(** print to the current err stream (note: only prints in developer mode) *)
|
|
let err fmt_string =
|
|
do_print_in_developer_mode err_formatter fmt_string
|
|
|
|
(** print immediately to standard error *)
|
|
let stderr fmt_string =
|
|
do_print F.err_formatter fmt_string
|
|
|
|
(** print immediately to standard output *)
|
|
let stdout fmt_string =
|
|
do_print F.std_formatter fmt_string
|
|
|
|
(** Type of location in ml source: __POS__ *)
|
|
type ml_loc = string * int * int * int
|
|
|
|
(** Convert a ml location to a string *)
|
|
let ml_loc_to_string (file, lnum, cnum, enum) =
|
|
Printf.sprintf "%s:%d:%d-%d:" file lnum cnum enum
|
|
|
|
(** Pretty print a location of ml source *)
|
|
let pp_ml_loc fmt ml_loc =
|
|
F.fprintf fmt "%s" (ml_loc_to_string ml_loc)
|
|
|
|
let pp_ml_loc_opt fmt ml_loc_opt =
|
|
if Config.developer_mode then match ml_loc_opt with
|
|
| None -> ()
|
|
| Some ml_loc -> F.fprintf fmt "(%a)" pp_ml_loc ml_loc
|
|
|
|
let assert_false ((file, lnum, cnum, _) as ml_loc) =
|
|
Printf.eprintf "\nASSERT FALSE %s\nCALL STACK\n%s\n%!"
|
|
(ml_loc_to_string ml_loc)
|
|
(Printexc.raw_backtrace_to_string (Printexc.get_callstack 1000));
|
|
raise (Assert_failure (file, lnum, cnum))
|
|
|
|
(** print a warning with information of the position in the ml source where it oririnated.
|
|
use as: warning_position "description" (try assert false with Assert_failure x -> x); *)
|
|
let warning_position (s: string) (ml_loc: ml_loc) =
|
|
err "WARNING: %s in %a@." s pp_ml_loc_opt (Some ml_loc)
|
|
|
|
(** dump a string *)
|
|
let d_str (s: string) = add_print_action (PTstr, Obj.repr s)
|
|
|
|
(** dump a string with the given color *)
|
|
let d_str_color (c: color) (s: string) = add_print_action (PTstr_color, Obj.repr (s, c))
|
|
|
|
(** dump an error string *)
|
|
let d_error (s: string) = add_print_action (PTerror, Obj.repr s)
|
|
|
|
(** dump a warning string *)
|
|
let d_warning (s: string) = add_print_action (PTwarning, Obj.repr s)
|
|
|
|
(** dump an info string *)
|
|
let d_info (s: string) = add_print_action (PTinfo, Obj.repr s)
|
|
|
|
(** dump a string plus newline *)
|
|
let d_strln (s: string) = add_print_action (PTstrln, Obj.repr s)
|
|
|
|
(** dump a string plus newline with the given color *)
|
|
let d_strln_color (c: color) (s: string) = add_print_action (PTstrln_color, Obj.repr (s, c))
|
|
|
|
(** dump a newline *)
|
|
let d_ln () = add_print_action (PTstrln, Obj.repr "")
|
|
|
|
(** dump an indentation *)
|
|
let d_indent indent =
|
|
let s = ref "" in
|
|
for _ = 1 to indent do s := " " ^ !s done;
|
|
if indent <> 0 then add_print_action (PTstr, Obj.repr !s)
|
|
|
|
(** dump command to increase the indentation level *)
|
|
let d_increase_indent (indent: int) =
|
|
add_print_action (PTincrease_indent, Obj.repr indent)
|
|
|
|
(** dump command to decrease the indentation level *)
|
|
let d_decrease_indent (indent: int) =
|
|
add_print_action (PTdecrease_indent, Obj.repr indent)
|
|
|
|
let log_progress_simple text =
|
|
if Config.show_progress_bar then
|
|
F.fprintf Format.err_formatter "%s@?" text
|
|
|
|
let log_progress_file () =
|
|
log_progress_simple Config.log_analysis_file
|
|
|
|
let log_progress_procedure () =
|
|
log_progress_simple Config.log_analysis_procedure
|
|
|
|
let log_progress_timeout_event failure_kind =
|
|
if Config.stats_mode then
|
|
begin
|
|
match failure_kind with
|
|
| SymOp.FKtimeout ->
|
|
log_progress_simple Config.log_analysis_wallclock_timeout
|
|
| SymOp.FKsymops_timeout _ ->
|
|
log_progress_simple Config.log_analysis_symops_timeout
|
|
| SymOp.FKrecursion_timeout _ ->
|
|
log_progress_simple Config.log_analysis_recursion_timeout
|
|
| SymOp.FKcrash msg ->
|
|
log_progress_simple (Printf.sprintf "%s(%s)" Config.log_analysis_crash msg)
|
|
end
|