From 741e527826fdb6da2cb24336aa1437b12041cd59 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Tue, 23 May 2017 05:16:49 -0700 Subject: [PATCH] [console] print progress-like messages on stderr Summary: Try and enforce the following rules: - stderr is for updating the user about progress or errors - Introduce Logging.progress that outputs to stderr, but honours --quiet - Logging.stderr is as before - Logging.out now prints to stderr (or to log files as before if set up) and not stdout. If some information should go on stdout then the user should be able to rely on it (ie, it's not just some progress message). For now only the summary of the errors is printed on stdout by default. - Logging.err* functions are gone. If the error is user-visible, it should be Logging.stderr, or `failwith`. If not, go to the same log file as other output, which personally I find much more convenient than having to dig through 2 log files every time I'm looking for some output. Reviewed By: jberdine Differential Revision: D5095720 fbshipit-source-id: 68999c9 --- infer/lib/python/infer.py | 2 +- infer/lib/python/inferlib/capture/util.py | 2 +- infer/lib/python/inferlib/issues.py | 17 ++-- infer/src/IR/Cfg.re | 2 - infer/src/IR/Cg.re | 4 +- infer/src/IR/Errlog.ml | 2 +- infer/src/IR/Procdesc.re | 4 +- infer/src/IR/Typ.re | 5 +- infer/src/backend/BuiltinDefn.ml | 6 +- infer/src/backend/InferAnalyze.re | 34 ++++---- infer/src/backend/OndemandCapture.ml | 6 +- infer/src/backend/abs.ml | 13 ++- infer/src/backend/cluster.ml | 2 +- infer/src/backend/dotty.ml | 10 +-- infer/src/backend/errdesc.ml | 3 +- infer/src/backend/exe_env.ml | 4 +- infer/src/backend/infer.ml | 28 ++++--- infer/src/backend/interproc.ml | 10 +-- infer/src/backend/match.ml | 9 ++- infer/src/backend/mergeCapture.ml | 8 +- infer/src/backend/ondemand.ml | 2 +- infer/src/backend/prop.ml | 16 ++-- infer/src/backend/rearrange.ml | 3 +- infer/src/backend/specs.ml | 2 +- infer/src/backend/state.ml | 2 +- infer/src/backend/symExec.ml | 3 +- infer/src/base/Config.ml | 16 ++-- infer/src/base/Config.mli | 3 +- infer/src/base/DB.ml | 9 +-- infer/src/base/Logging.ml | 80 +++++++------------ infer/src/base/Logging.mli | 18 ++--- infer/src/base/Process.ml | 12 +-- infer/src/base/Serialization.ml | 4 +- .../src/bufferoverrun/bufferOverrunChecker.ml | 42 +++++----- .../src/bufferoverrun/bufferOverrunDomain.ml | 2 +- infer/src/clang/CType.ml | 4 +- infer/src/clang/Capture.re | 3 +- infer/src/clang/cFrontend_checkers_main.ml | 4 +- infer/src/clang/cFrontend_errors.ml | 15 +--- infer/src/clang/cTrans.ml | 3 +- infer/src/clang/cTrans_utils.ml | 9 +-- infer/src/clang/cType_to_sil_type.ml | 6 +- infer/src/eradicate/AnnotatedSignature.ml | 4 +- infer/src/harness/inhabit.ml | 10 +-- .../integration/CaptureCompilationDatabase.ml | 2 +- infer/src/java/jFrontend.ml | 2 +- infer/src/java/jTrans.ml | 6 +- 47 files changed, 201 insertions(+), 252 deletions(-) diff --git a/infer/lib/python/infer.py b/infer/lib/python/infer.py index b318d7731..bc90ced39 100755 --- a/infer/lib/python/infer.py +++ b/infer/lib/python/infer.py @@ -172,7 +172,7 @@ def main(): logging.info('Capture phase was successful') elif capture_module_name is not None: # There was a command, but it's not supported - utils.stdout('Command "{cmd}" not recognised' + utils.stderr('Command "{cmd}" not recognised' .format(cmd='' if capture_module_name is None else capture_module_name)) global_argparser.print_help() diff --git a/infer/lib/python/inferlib/capture/util.py b/infer/lib/python/inferlib/capture/util.py index 7102046e7..32e950f89 100644 --- a/infer/lib/python/inferlib/capture/util.py +++ b/infer/lib/python/inferlib/capture/util.py @@ -34,7 +34,7 @@ def run_compilation_commands(cmds, clean_cmd): """ # TODO call it in parallel if len(cmds) == 0: - utils.stdout('Nothing to compile. Try running `{}` first.' + utils.stderr('Nothing to compile. Try running `{}` first.' .format(clean_cmd)) return os.EX_NOINPUT for cmd in cmds: diff --git a/infer/lib/python/inferlib/issues.py b/infer/lib/python/inferlib/issues.py index 0285f2ffe..04cc297a9 100644 --- a/infer/lib/python/inferlib/issues.py +++ b/infer/lib/python/inferlib/issues.py @@ -87,6 +87,7 @@ def text_of_report(report): def _text_of_report_list(project_root, reports, bugs_txt_path, limit=None, + console_out=False, formatter=colorize.TERMINAL_FORMATTER): n_issues = len(reports) if n_issues == 0: @@ -153,17 +154,24 @@ def _text_of_report_list(project_root, reports, bugs_txt_path, limit=None, issues_found = 'Found {n_issues}'.format( n_issues=utils.get_plural('issue', n_issues), ) - msg = '{issues_found}\n\n{issues}\n\n{header}\n\n{summary}'.format( + bug_list = '{issues_found}\n\n{issues}\n\n'.format( issues_found=colorize.color(issues_found, colorize.HEADER, formatter), issues=text_errors, + ) + summary = '{header}\n\n{summary}'.format( header=colorize.color('Summary of the reports', colorize.HEADER, formatter), summary='\n'.join(types_text_list), ) - return msg + if console_out: + utils.stderr('') + utils.stderr(bug_list) + utils.stdout(summary) + + return bug_list + summary def _is_user_visible(project_root, report): @@ -175,9 +183,8 @@ def print_and_save_errors(infer_out, project_root, json_report, bugs_out, pmd_xml): errors = utils.load_json_from_path(json_report) errors = [e for e in errors if _is_user_visible(project_root, e)] - console_out = _text_of_report_list(project_root, errors, bugs_out, - limit=10) - utils.stdout('\n' + console_out) + _text_of_report_list(project_root, errors, bugs_out, console_out=True, + limit=10) plain_out = _text_of_report_list(project_root, errors, bugs_out, formatter=colorize.PLAIN_FORMATTER) with codecs.open(bugs_out, 'w', diff --git a/infer/src/IR/Cfg.re b/infer/src/IR/Cfg.re index 3d7881862..0b1a1ff45 100644 --- a/infer/src/IR/Cfg.re +++ b/infer/src/IR/Cfg.re @@ -110,8 +110,6 @@ let check_cfg_connectedness cfg => { let broken = List.exists f::broken_node nodes; if broken { L.out "\n ***BROKEN CFG: '%s'\n" pname - } else { - L.out "\n ***CONNECTED CFG: '%s'\n" pname } }; let pdescs = get_all_procs cfg; diff --git a/infer/src/IR/Cg.re b/infer/src/IR/Cg.re index c12502c6f..12325ffcd 100644 --- a/infer/src/IR/Cg.re +++ b/infer/src/IR/Cg.re @@ -136,7 +136,7 @@ let get_ancestors (g: t) node => { info.ancestors = Some ancestors; let size = Typ.Procname.Set.cardinal ancestors; if (size > 1000) { - L.err "%a has %d ancestors@." Typ.Procname.pp node size + L.out "%a has %d ancestors@." Typ.Procname.pp node size }; ancestors | Some ancestors => ancestors @@ -153,7 +153,7 @@ let get_heirs (g: t) node => { info.heirs = Some heirs; let size = Typ.Procname.Set.cardinal heirs; if (size > 1000) { - L.err "%a has %d heirs@." Typ.Procname.pp node size + L.out "%a has %d heirs@." Typ.Procname.pp node size }; heirs | Some heirs => heirs diff --git a/infer/src/IR/Errlog.ml b/infer/src/IR/Errlog.ml index d3c8ceefb..e9392adfe 100644 --- a/infer/src/IR/Errlog.ml +++ b/infer/src/IR/Errlog.ml @@ -262,7 +262,7 @@ let log_issue err_kind err_log loc (node_id, node_key) session ltr ?linters_def_ | _ -> added in let print_now () = let ex_name, desc, ml_loc_opt, _, _, _, _ = Exceptions.recognize_exception exn in - L.err "@\n%a@\n@?" + L.out "@\n%a@\n@?" (Exceptions.pp_err ~node_key loc err_kind ex_name desc ml_loc_opt) (); if err_kind <> Exceptions.Kerror then begin let warn_str = diff --git a/infer/src/IR/Procdesc.re b/infer/src/IR/Procdesc.re index 3c70b4e12..cdc7fc78b 100644 --- a/infer/src/IR/Procdesc.re +++ b/infer/src/IR/Procdesc.re @@ -119,9 +119,7 @@ module Node = { /** Get the name of the procedure the node belongs to */ let get_proc_name node => switch node.pname_opt { - | None => - L.out "get_proc_name: at node %d@\n" node.id; - assert false + | None => failwithf "get_proc_name: at node %d" node.id | Some pname => pname }; diff --git a/infer/src/IR/Typ.re b/infer/src/IR/Typ.re index 44a5c17d1..5eea23f98 100644 --- a/infer/src/IR/Typ.re +++ b/infer/src/IR/Typ.re @@ -371,10 +371,7 @@ let name typ => let unsome s => fun | Some default_typ => default_typ - | None => { - L.err "No default typ in %s@." s; - assert false - }; + | None => failwithf "No default typ in %s@." s; /** turn a *T into a T. fails if [typ] is not a pointer type */ diff --git a/infer/src/backend/BuiltinDefn.ml b/infer/src/backend/BuiltinDefn.ml index a994bbfaf..e4a1fa907 100644 --- a/infer/src/backend/BuiltinDefn.ml +++ b/infer/src/backend/BuiltinDefn.ml @@ -130,13 +130,13 @@ let execute___set_array_length { Builtin.tenv; pdesc; prop_; path; ret_id; args; let execute___print_value { Builtin.tenv; pdesc; prop_; path; args; } : Builtin.ret_typ = - L.err "__print_value: "; + L.out "__print_value: "; let pname = Procdesc.get_proc_name pdesc in let do_arg (lexp, _) = let n_lexp, _ = check_arith_norm_exp tenv pname lexp prop_ in - L.err "%a " Exp.pp n_lexp in + L.out "%a " Exp.pp n_lexp in List.iter ~f:do_arg args; - L.err "@."; + L.out "@."; [(prop_, path)] let is_undefined_opt tenv prop n_lexp = diff --git a/infer/src/backend/InferAnalyze.re b/infer/src/backend/InferAnalyze.re index 761e9ead8..b694cd578 100644 --- a/infer/src/backend/InferAnalyze.re +++ b/infer/src/backend/InferAnalyze.re @@ -62,7 +62,7 @@ let analyze_cluster_tasks cluster_num (cluster: Cluster.t) :Tasks.t => { let exe_env = Exe_env.from_cluster cluster; let defined_procs = Cg.get_defined_nodes (Exe_env.get_cg exe_env); let num_procs = List.length defined_procs; - L.err "@.Processing cluster #%d with %d procedures@." (cluster_num + 1) num_procs; + L.out "@.Processing cluster #%d with %d procedures@." (cluster_num + 1) num_procs; analyze_exe_env_tasks cluster exe_env }; @@ -82,29 +82,29 @@ let output_json_makefile_stats clusters => { let process_cluster_cmdline fname => switch (Cluster.load_from_file (DB.filename_from_string fname)) { - | None => L.err "Cannot find cluster file %s@." fname + | None => L.stderr "Cannot find cluster file %s@." fname | Some (nr, cluster) => analyze_cluster (nr - 1) cluster }; -let print_stdout_legend () => { - L.stdout "Starting analysis...@\n"; - L.stdout "@\n"; - L.stdout "legend:@\n"; - L.stdout " \"%s\" analyzing a file@\n" Config.log_analysis_file; - L.stdout " \"%s\" analyzing a procedure@\n" Config.log_analysis_procedure; +let print_legend () => { + L.progress "Starting analysis...@\n"; + L.progress "@\n"; + L.progress "legend:@\n"; + L.progress " \"%s\" analyzing a file@\n" Config.log_analysis_file; + L.progress " \"%s\" analyzing a procedure@\n" Config.log_analysis_procedure; if (Config.stats_mode || Config.debug_mode) { - L.stdout " \"%s\" analyzer crashed@\n" Config.log_analysis_crash; - L.stdout + L.progress " \"%s\" analyzer crashed@\n" Config.log_analysis_crash; + L.progress " \"%s\" timeout: procedure analysis took too much time@\n" Config.log_analysis_wallclock_timeout; - L.stdout + L.progress " \"%s\" timeout: procedure analysis took too many symbolic execution steps@\n" Config.log_analysis_symops_timeout; - L.stdout + L.progress " \"%s\" timeout: procedure analysis took too many recursive iterations@\n" Config.log_analysis_recursion_timeout }; - L.stdout "@\n@?" + L.progress "@\n@?" }; let cluster_should_be_analyzed cluster => { @@ -114,7 +114,7 @@ let cluster_should_be_analyzed cluster => { let check_modified () => { let modified = DB.file_was_updated_after_start (DB.filename_from_string fname); if (modified && Config.developer_mode) { - L.stdout "Modified: %s@." fname + L.progress "Modified: %s@." fname }; modified }; @@ -146,7 +146,7 @@ let main makefile => { let all_clusters = DB.find_source_dirs (); let clusters_to_analyze = List.filter f::cluster_should_be_analyzed all_clusters; let n_clusters_to_analyze = List.length clusters_to_analyze; - L.stdout + L.progress "Found %d%s source file%s to analyze in %s@." n_clusters_to_analyze ( @@ -171,7 +171,7 @@ let main makefile => { if Config.print_active_checkers { L.stderr "Active checkers: %a@." RegisterCheckers.pp_active_checkers () }; - print_stdout_legend (); + print_legend (); if (Config.per_procedure_parallelism && not (is_java ())) { /* Java uses ZipLib which is incompatible with forking */ /* per-procedure parallelism */ @@ -195,7 +195,7 @@ let main makefile => { } else { /* This branch is reached when -j 1 is used */ List.iteri f::analyze_cluster clusters_to_analyze; - L.stdout "@\nAnalysis finished in %as@." Pp.elapsed_time () + L.progress "@\nAnalysis finished in %as@." Pp.elapsed_time () }; output_json_makefile_stats clusters_to_analyze } diff --git a/infer/src/backend/OndemandCapture.ml b/infer/src/backend/OndemandCapture.ml index 45ef34d17..2cde80942 100644 --- a/infer/src/backend/OndemandCapture.ml +++ b/infer/src/backend/OndemandCapture.ml @@ -28,7 +28,7 @@ let try_capture (attributes : ProcAttributes.t) : ProcAttributes.t option = Cfg.store_cfg_to_file *) let cfg_filename = DB.source_dir_get_internal_file source_dir ".cfg" in if not (DB.file_exists cfg_filename) then ( - Logging.out "Started capture of %a...@\n" SourceFile.pp definition_file; + Logging.out_debug "Started capture of %a...@\n" SourceFile.pp definition_file; Timeout.suspend_existing_timeout ~keep_symop_total:true; protect ~f:(fun () -> CaptureCompilationDatabase.capture_file_in_database cdb definition_file) @@ -37,13 +37,13 @@ let try_capture (attributes : ProcAttributes.t) : ProcAttributes.t option = Option.is_none (AttributesTable.load_defined_attributes ~cache_none:false attributes.proc_name) then ( (* peek at the results to know if capture succeeded, but only in debug mode *) - Logging.out + Logging.out_debug "Captured file %a to get procedure %a but it wasn't found there@\n" SourceFile.pp definition_file Typ.Procname.pp attributes.proc_name ) ) else ( - Logging.out + Logging.out_debug "Wanted to capture file %a to get procedure %a but file was already captured@\n" SourceFile.pp definition_file Typ.Procname.pp attributes.proc_name diff --git a/infer/src/backend/abs.ml b/infer/src/backend/abs.ml index f25388438..a5bcaece1 100644 --- a/infer/src/backend/abs.ml +++ b/infer/src/backend/abs.ml @@ -99,7 +99,7 @@ let mk_rule_ptspts_ls tenv impl_ok1 impl_ok2 (para: Sil.hpara) = let (para_fst_start, para_fst_rest) = let mark_impl_flag hpred = { Match.hpred = hpred; Match.flag = impl_ok1 } in match para_fst with - | [] -> L.out "@.@.ERROR (Empty Para): %a @.@." (Sil.pp_hpara Pp.text) para; assert false + | [] -> failwithf "mk_rule_ptspts_ls (Empty Para): %a" (Sil.pp_hpara Pp.text) para | hpred :: hpreds -> let hpat = mark_impl_flag hpred in let hpats = List.map ~f:mark_impl_flag hpreds in @@ -128,7 +128,7 @@ let mk_rule_ptsls_ls tenv k2 impl_ok1 impl_ok2 para = let (ids_exist, para_inst) = Sil.hpara_instantiate para exp_base exp_next exps_shared in let (para_inst_start, para_inst_rest) = match para_inst with - | [] -> L.out "@.@.ERROR (Empty Para): %a @.@." (Sil.pp_hpara Pp.text) para; assert false + | [] -> failwithf "mk_rule_ptsls_ls (Empty Para): %a" (Sil.pp_hpara Pp.text) para | hpred :: hpreds -> let allow_impl hpred = { Match.hpred = hpred; Match.flag = impl_ok1 } in (allow_impl hpred, List.map ~f:allow_impl hpreds) in @@ -252,7 +252,7 @@ let mk_rule_ptspts_dll tenv impl_ok1 impl_ok2 para = let (para_fst_start, para_fst_rest) = let mark_impl_flag hpred = { Match.hpred = hpred; Match.flag = impl_ok1 } in match para_fst with - | [] -> L.out "@.@.ERROR (Empty DLL para): %a@.@." (Sil.pp_hpara_dll Pp.text) para; assert false + | [] -> failwithf "mk_rule_ptspts_dll (Empty DLL para): %a" (Sil.pp_hpara_dll Pp.text) para | hpred :: hpreds -> let hpat = mark_impl_flag hpred in let hpats = List.map ~f:mark_impl_flag hpreds in @@ -422,7 +422,7 @@ let typ_get_recursive_flds tenv typ_exp = match Tenv.lookup tenv name with | Some { fields } -> List.map ~f:fst3 (List.filter ~f:(filter typ) fields) | None -> - L.err "@.typ_get_recursive: unexpected type expr: %a@." Exp.pp typ_exp; + L.out "@.typ_get_recursive: unexpected type expr: %a@." Exp.pp typ_exp; [] (* ToDo: assert false *) ) | Tint _ | Tvoid | Tfun _ | Tptr _ | Tfloat _ | Tarray _ -> [] @@ -430,8 +430,7 @@ let typ_get_recursive_flds tenv typ_exp = | Exp.Var _ -> [] (* type of |-> not known yet *) | Exp.Const _ -> [] | _ -> - L.err "@.typ_get_recursive: unexpected type expr: %a@." Exp.pp typ_exp; - assert false + failwithf "@.typ_get_recursive: unexpected type expr: %a@." Exp.pp typ_exp let discover_para_roots tenv p root1 next1 root2 next2 : Sil.hpara option = let eq_arg1 = Exp.equal root1 next1 in @@ -602,7 +601,7 @@ let eqs_solve ids_in eqs_in = if not (List.exists ~f:(fun id' -> Ident.equal id id') ids_in) then None else let sub' = match Sil.extend_sub sub id e with - | None -> L.out "@.@.ERROR : Buggy Implementation.@.@."; assert false + | None -> failwithf "ERROR : Buggy Implementation" | Some sub' -> sub' in let eqs_rest' = eqs_sub sub' eqs_rest in solve sub' eqs_rest' in diff --git a/infer/src/backend/cluster.ml b/infer/src/backend/cluster.ml index c627b4361..5b836fb7f 100644 --- a/infer/src/backend/cluster.ml +++ b/infer/src/backend/cluster.ml @@ -41,7 +41,7 @@ let pp_cluster fmt (nr, cluster) = let pp_cl fmt n = Format.fprintf fmt "%s" (cl_name n) in store_to_file (DB.filename_from_string fname) (nr, cluster); F.fprintf fmt "%a: @\n" pp_cl nr; - F.fprintf fmt "\t$(INFERANALYZE) --cluster '%s'@\n" fname; + F.fprintf fmt "\t@@$(INFERANALYZE) --cluster '%s'@\n" fname; (* touch the target of the rule to let `make` know that the job has been done *) F.fprintf fmt "\t@@touch $@@@\n"; F.fprintf fmt "@\n" diff --git a/infer/src/backend/dotty.ml b/infer/src/backend/dotty.ml index 01fd5c19d..d31d68cb6 100644 --- a/infer/src/backend/dotty.ml +++ b/infer/src/backend/dotty.ml @@ -113,10 +113,8 @@ let strip_special_chars b = let replace st c c' = if String.contains st c then begin let idx = String.index_exn st c in - try - String.set st idx c'; - st - with Invalid_argument _ -> L.out "@\n@\n Invalid argument!!! @\n @.@.@."; assert false + String.set st idx c'; + st end else st in let s0 = replace b '(' 'B' in let s1 = replace s0 '$' 'D' in @@ -429,7 +427,7 @@ let rec compute_target_struct_fields dotnodes list_fld p f lambda cycle = end else [(LinkStructToExp, Fieldname.to_string fn, n,"")] | _ -> (* by construction there must be at most 2 nodes for an expression*) - L.out "@\n Too many nodes! Error! @\n@.@."; assert false) + failwithf "Got more than 2 nodes, this should never happen!") | Sil.Estruct (_, _) -> [] (* inner struct are printed by print_struc function *) | Sil.Earray _ -> [] (* inner arrays are printed by print_array function *) in match list_fld with @@ -462,7 +460,7 @@ let rec compute_target_array_elements dotnodes list_elements p f lambda = end else [(LinkArrayToExp, Exp.to_string idx, n,"")] | _ -> (* by construction there must be at most 2 nodes for an expression*) - L.out "@\n Too many nodes! Error! @\n@.@."; assert false + failwithf "Got more than 2 nodes, this should never happen!" ) | Sil.Estruct (_, _) -> [] (* inner struct are printed by print_struc function *) | Sil.Earray _ ->[] (* inner arrays are printed by print_array function *) diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml index bf8b3d0a5..eadfa991a 100644 --- a/infer/src/backend/errdesc.ml +++ b/infer/src/backend/errdesc.ml @@ -1155,5 +1155,4 @@ let explain_null_test_after_dereference tenv exp node line loc = (** Print a warning to the err stream at the given location (note: only prints in developer mode) *) let warning_err loc fmt_string = - L.err ("%a: Warning: " ^^ fmt_string) - Location.pp loc + L.out ("%a: Warning: " ^^ fmt_string) Location.pp loc diff --git a/infer/src/backend/exe_env.ml b/infer/src/backend/exe_env.ml index 3c9f7e206..e76d00767 100644 --- a/infer/src/backend/exe_env.ml +++ b/infer/src/backend/exe_env.ml @@ -87,7 +87,7 @@ let add_cg (exe_env: t) (source_dir : DB.source_dir) = let cg_fname = DB.source_dir_get_internal_file source_dir ".cg" in match Cg.load_from_file cg_fname with | None -> - L.stderr "cannot load %s@." (DB.filename_to_string cg_fname) + L.stderr "Error: cannot load %s@." (DB.filename_to_string cg_fname) | Some cg -> let source = Cg.get_source cg in exe_env.source_files <- SourceFile.Set.add source exe_env.source_files; @@ -129,7 +129,7 @@ let get_file_data exe_env pname = let source_file_opt = match AttributesTable.load_attributes ~cache:true pname with | None -> - L.err "can't find tenv_cfg_object for %a@." Typ.Procname.pp pname; + L.out "can't find tenv_cfg_object for %a@." Typ.Procname.pp pname; None | Some proc_attributes when Config.reactive_capture -> let get_captured_file {ProcAttributes.source_file_captured} = source_file_captured in diff --git a/infer/src/backend/infer.ml b/infer/src/backend/infer.ml index 3b8e74263..a97231c7c 100644 --- a/infer/src/backend/infer.ml +++ b/infer/src/backend/infer.ml @@ -220,7 +220,7 @@ let check_xcpretty () = | Ok () -> () | Error _ -> L.stderr - "@.xcpretty not found in the path. Please, install xcpretty \ + "@.xcpretty not found in the path. Please consider installing xcpretty \ for a more robust integration with xcodebuild. Otherwise use the option \ --no-xcpretty.@.@."; exit 1 @@ -238,26 +238,26 @@ let capture = function | Analyze -> () | BuckCompilationDB (prog, args) -> - L.stdout "Capturing using Buck's compilation database...@."; + L.progress "Capturing using Buck's compilation database...@."; let json_cdb = CaptureCompilationDatabase.get_compilation_database_files_buck ~prog ~args in capture_with_compilation_database json_cdb | BuckGenrule path -> - L.stdout "Capturing for Buck genrule compatibility...@."; + L.progress "Capturing for Buck genrule compatibility...@."; JMain.from_arguments path | Clang (compiler, prog, args) -> - L.stdout "Capturing in make/cc mode...@."; + L.progress "Capturing in make/cc mode...@."; Clang.capture compiler ~prog ~args | ClangCompilationDB db_files -> - L.stdout "Capturing using compilation database...@."; + L.progress "Capturing using compilation database...@."; capture_with_compilation_database db_files | Javac (compiler, prog, args) -> - L.stdout "Capturing in javac mode...@."; + L.progress "Capturing in javac mode...@."; Javac.capture compiler ~prog ~args | Maven (prog, args) -> - L.stdout "Capturing in maven mode...@."; + L.progress "Capturing in maven mode...@."; Maven.capture ~prog ~args | PythonCapture (build_system, build_cmd) -> - L.stdout "Capturing in %s mode...@." (string_of_build_system build_system); + L.progress "Capturing in %s mode...@." (string_of_build_system build_system); let in_buck_mode = equal_build_system build_system BBuck in let infer_py = Config.lib_dir ^/ "python" ^/ "infer.py" in let args = @@ -312,7 +312,7 @@ let capture = function () ) | XcodeXcpretty (prog, args) -> - L.stdout "Capturing using xcodebuild and xcpretty...@."; + L.progress "Capturing using xcodebuild and xcpretty...@."; check_xcpretty (); let json_cdb = CaptureCompilationDatabase.get_compilation_database_files_xcodebuild ~prog ~args in @@ -344,9 +344,11 @@ let report () = let report_json = Some (Config.results_dir ^/ "report.json") in InferPrint.main ~report_csv ~report_json ; (* Post-process the report according to the user config. By default, calls report.py to create a - human-readable report. *) - match Config.buck_cache_mode, Config.report_hook with - | true, _ (* do not bother calling the report hook when called from within Buck *) + human-readable report. + + Do not bother calling the report hook when called from within Buck or in quiet mode. *) + match Config.quiet || Config.buck_cache_mode, Config.report_hook with + | true, _ | false, None -> () | false, Some prog -> @@ -550,7 +552,7 @@ let () = Logging.set_log_file_identifier CommandLineOption.Analyze (Option.map ~f:Filename.basename Config.cluster_cmdline); if Sys.file_exists Config.results_dir <> `Yes then ( - L.err "ERROR: results directory %s does not exist@.@." Config.results_dir; + L.stderr "ERROR: results directory %s does not exist@.@." Config.results_dir; Config.print_usage_exit () ); InferAnalyze.register_perf_stats_report (); diff --git a/infer/src/backend/interproc.ml b/infer/src/backend/interproc.ml index 1e67e65a8..186e8aa66 100644 --- a/infer/src/backend/interproc.ml +++ b/infer/src/backend/interproc.ml @@ -117,8 +117,7 @@ module Worklist = struct Procdesc.NodeMap.add min.node (min.visits + 1) wl.visit_map; (* increase the visits *) min.node with Not_found -> begin - L.out "@\n...Work list is empty! Impossible to remove edge...@\n"; - assert false + failwithf "Work list is empty! Impossible to remove edge." end end (* =============== END of module Worklist =============== *) @@ -162,8 +161,7 @@ let path_set_checkout_todo (wl : Worklist.t) (node: Procdesc.Node.t) : Paths.Pat Hashtbl.replace wl.Worklist.path_set_visited node_id new_visited; todo with Not_found -> - L.out "@.@.ERROR: could not find todo for node %a@.@." Procdesc.Node.pp node; - assert false + failwithf "could not find todo for node %a" Procdesc.Node.pp node (* =============== END of the edge_set object =============== *) @@ -1363,10 +1361,10 @@ let perform_transition proc_desc tenv proc_name = with exn when SymOp.exn_not_failure exn -> apply_start_node do_after_node; Config.allow_leak := allow_leak; - L.err "Error in collect_preconditions for %a@." Typ.Procname.pp proc_name; + L.out "Error in collect_preconditions for %a@." Typ.Procname.pp proc_name; let err_name, _, ml_loc_opt, _, _, _, _ = Exceptions.recognize_exception exn in let err_str = "exception raised " ^ (Localise.to_issue_id err_name) in - L.err "Error: %s %a@." err_str L.pp_ml_loc_opt ml_loc_opt; + L.out "Error: %s %a@." err_str L.pp_ml_loc_opt ml_loc_opt; [] in transition_footprint_re_exe tenv proc_name joined_pres in match Specs.get_summary proc_name with diff --git a/infer/src/backend/match.ml b/infer/src/backend/match.ml index 865fe4f68..cf1d3cc90 100644 --- a/infer/src/backend/match.ml +++ b/infer/src/backend/match.ml @@ -143,10 +143,11 @@ and isel_match isel1 sub vars isel2 = let sanity_check = not (List.exists ~f:(fun id -> Sil.ident_in_exp id idx2) vars) in if (not sanity_check) then begin let pe = Pp.text in - L.out "@[.... Sanity Check Failure while Matching Index-Strexps ....@."; - L.out "@[<4> IDX1: %a, STREXP1: %a@." (Sil.pp_exp_printenv pe) idx1 (Sil.pp_sexp pe) se1'; - L.out "@[<4> IDX2: %a, STREXP2: %a@\n@." (Sil.pp_exp_printenv pe) idx2 (Sil.pp_sexp pe) se2'; - assert false + failwithf "@[.... Sanity Check Failure while Matching Index-Strexps ....@\n\ + @[<4> IDX1: %a, STREXP1: %a@\n\ + @[<4> IDX2: %a, STREXP2: %a@\n@." + (Sil.pp_exp_printenv pe) idx1 (Sil.pp_sexp pe) se1' + (Sil.pp_exp_printenv pe) idx2 (Sil.pp_sexp pe) se2' end else if Exp.equal idx1 idx2 then begin match strexp_match se1' sub vars se2' with diff --git a/infer/src/backend/mergeCapture.ml b/infer/src/backend/mergeCapture.ml index e12e2b990..3168361f1 100644 --- a/infer/src/backend/mergeCapture.ml +++ b/infer/src/backend/mergeCapture.ml @@ -202,10 +202,10 @@ let process_merge_file deps_file = ~f:(fun lines -> List.iter ~f:process_line lines) (Utils.read_file deps_file); create_multilinks (); - L.stdout "Captured results merged.@."; - L.stdout "Targets merged: %d@." stats.targets_merged; - L.stdout "Files linked: %d@." stats.files_linked; - L.stdout "Files multilinked: %d@." stats.files_multilinked + L.progress "Captured results merged.@."; + L.progress "Targets merged: %d@." stats.targets_merged; + L.progress "Files linked: %d@." stats.files_linked; + L.progress "Files multilinked: %d@." stats.files_multilinked let merge_captured_targets () = diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index 4d2971239..68b7ef509 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -128,7 +128,7 @@ let run_proc_analysis ~propagate_exceptions analyze_proc curr_pdesc callee_pdesc (* Dot means start of a procedure *) L.log_progress_procedure (); - if Config.trace_ondemand then L.stderr "[%d] run_proc_analysis %a -> %a@." + if Config.trace_ondemand then L.progress "[%d] run_proc_analysis %a -> %a@." !nesting Typ.Procname.pp curr_pname Typ.Procname.pp callee_pname; diff --git a/infer/src/backend/prop.ml b/infer/src/backend/prop.ml index ee8e8b446..098b1220c 100644 --- a/infer/src/backend/prop.ml +++ b/infer/src/backend/prop.ml @@ -1356,8 +1356,7 @@ module Normalize = struct | Var _ -> Estruct ([], inst) | te -> - L.err "trying to create ptsto with type: %a@\n@." (Sil.pp_texp_full Pp.text) te; - assert false in + failwithf "trying to create ptsto with type: %a@\n@." (Sil.pp_texp_full Pp.text) te in let strexp : Sil.strexp = match expo with | Some e -> Eexp (e, inst) | None -> default_strexp () in @@ -1853,7 +1852,7 @@ let prop_dfs_sort tenv p = let sigma_fp = p.sigma_fp in let sigma_fp' = sigma_dfs_sort tenv sigma_fp in let p' = set p ~sigma:sigma' ~sigma_fp:sigma_fp' in - (* L.err "@[<2>P SORTED:@\n%a@\n@." pp_prop p'; *) + (* L.out "@[<2>P SORTED:@\n%a@\n@." pp_prop p'; *) p' let prop_fav_add_dfs tenv fav prop = @@ -2361,11 +2360,12 @@ let prop_iter_make_id_primed tenv id iter = begin match eq with | Aeq (Var id1, e1) when Sil.ident_in_exp id1 e1 -> - L.out "@[<2>#### ERROR: an assumption of the analyzer broken ####@\n"; - L.out "Broken Assumption: id notin e for all (id,e) in sub@\n"; - L.out "(id,e) : (%a,%a)@\n" (Ident.pp Pp.text) id1 Exp.pp e1; - L.out "PROP : %a@\n@." (pp_prop Pp.text) (prop_iter_to_prop tenv iter); - assert false + failwithf "@[<2>#### ERROR: an assumption of the analyzer broken ####@\n\ + Broken Assumption: id notin e for all (id,e) in sub@\n\ + (id,e) : (%a,%a)@\n\ + PROP : %a@\n@." + (Ident.pp Pp.text) id1 Exp.pp e1 + (pp_prop Pp.text) (prop_iter_to_prop tenv iter) | Aeq (Var id1, e1) when Ident.equal pid id1 -> split pairs_unpid ((id1, e1):: pairs_pid) eqs_cur | Aeq (Var id1, e1) -> diff --git a/infer/src/backend/rearrange.ml b/infer/src/backend/rearrange.ml index d886d5b6b..617d04e86 100644 --- a/infer/src/backend/rearrange.ml +++ b/infer/src/backend/rearrange.ml @@ -432,8 +432,7 @@ let mk_ptsto_exp_footprint * will fix them during the re - execution phase *) if not (Config.angelic_execution && !Config.footprint) then begin - if Config.developer_mode then - L.err "!!!! Footprint Error, Bad Root : %a !!!! @\n" Exp.pp lexp; + L.out "!!!! Footprint Error, Bad Root : %a !!!! @\n" Exp.pp lexp; let deref_str = Localise.deref_str_dangling None in let err_desc = Errdesc.explain_dereference tenv deref_str orig_prop (State.get_loc ()) in diff --git a/infer/src/backend/specs.ml b/infer/src/backend/specs.ml index dbe1ab94e..a823f1403 100644 --- a/infer/src/backend/specs.ml +++ b/infer/src/backend/specs.ml @@ -152,7 +152,7 @@ let visited_str vis = begin let ss = ref "" in List.iter ~f:(fun n -> ss := !ss ^ " " ^ string_of_int n) ns; - L.err "Node %d has lines %s@." node !ss + L.out "Node %d has lines %s@." node !ss end; *) List.iter ~f:(fun n -> lines := Int.Set.add !lines n) ns in Visitedset.iter do_one vis; diff --git a/infer/src/backend/state.ml b/infer/src/backend/state.ml index c23102299..2706f0ff1 100644 --- a/infer/src/backend/state.ml +++ b/infer/src/backend/state.ml @@ -319,7 +319,7 @@ type log_issue = let process_execution_failures (log_issue : log_issue) pname = let do_failure _ fs = - (* L.err "Node:%a node_ok:%d node_fail:%d@." Procdesc.Node.pp node fs.node_ok fs.node_fail; *) + (* L.out "Node:%a node_ok:%d node_fail:%d@." Procdesc.Node.pp node fs.node_ok fs.node_fail; *) match fs.node_ok, fs.first_failure with | 0, Some (loc, key, _, loc_trace, exn) when not Config.debug_exceptions -> let ex_name, _, ml_loc_opt, _, _, _, _ = Exceptions.recognize_exception exn in diff --git a/infer/src/backend/symExec.ml b/infer/src/backend/symExec.ml index 5a56b82ff..b167e5892 100644 --- a/infer/src/backend/symExec.ml +++ b/infer/src/backend/symExec.ml @@ -1235,8 +1235,7 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path | [], _ -> ret_old_path [prop_] | _ -> - L.err "Pvar %a appears on the LHS of >1 heap predicate!@." (Pvar.pp Pp.text) pvar; - assert false + failwithf "Pvar %a appears on the LHS of >1 heap predicate!@." (Pvar.pp Pp.text) pvar end | Sil.Abstract _ -> let node = State.get_node () in diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 6f148c763..d7aee1602 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -952,11 +952,6 @@ and eradicate_verbose = CLOpt.mk_bool ~long:"eradicate-verbose" "Print initial and final typestates" -(* Use file for the err channel *) -and err_file = - CLOpt.mk_string ~deprecated:["err_file"] ~long:"err-file" ~default:"" - ~meta:"file" "" - and fail_on_bug = CLOpt.mk_bool ~deprecated:["-fail-on-bug"] ~long:"fail-on-issue" ~default:false ~in_help:CLOpt.[Run, manual_generic] @@ -1091,6 +1086,10 @@ and latex = ~meta:"file" "Write a latex report of the analysis results to a file" +and log_file = + CLOpt.mk_path_opt ~deprecated:["out_file"; "-out-file"] ~long:"log-file" + ~meta:"file" "Specify the file to use for logging" + and linter = CLOpt.mk_string_opt ~long:"linter" ~in_help:CLOpt.[Capture, manual_clang_linters] "From the linters available, only run this one linter. \ @@ -1168,10 +1167,6 @@ and only_footprint = CLOpt.mk_bool ~deprecated:["only_footprint"] ~long:"only-footprint" "Skip the re-execution phase" -and out_file = - CLOpt.mk_path ~deprecated:["out_file"] ~long:"out-file" ~default:"" - ~meta:"file" "Specify the file for the non-error logs of the analyzer" - and patterns_modeled_expensive = let long = "modeled-expensive" in (long, @@ -1768,7 +1763,6 @@ and eradicate_propagate_return_nullable = !eradicate_propagate_return_nullable and eradicate_return_over_annotated = !eradicate_return_over_annotated and eradicate_debug = !eradicate_debug and eradicate_verbose = !eradicate_verbose -and err_file_cmdline = !err_file and fail_on_bug = !fail_on_bug and failures_allowed = !failures_allowed and fcp_apple_clang = !fcp_apple_clang @@ -1803,6 +1797,7 @@ and load_average = match !load_average with | _ -> !load_average and load_analysis_results = !load_results +and log_file = !log_file and makefile_cmdline = !makefile and merge = !merge and ml_buckets = !ml_buckets @@ -1813,7 +1808,6 @@ and nelseg = !nelseg and no_translate_libs = not !headers and objc_memory_model_on = !objc_memory_model and only_footprint = !only_footprint -and out_file_cmdline = !out_file and patterns_never_returning_null = match patterns_never_returning_null with (k,r) -> (k,!r) and patterns_skip_translation = match patterns_skip_translation with (k,r) -> (k,!r) and patterns_modeled_expensive = match patterns_modeled_expensive with (k,r) -> (k,!r) diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 4cd267230..f789a6e57 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -223,7 +223,6 @@ val eradicate_propagate_return_nullable : bool val eradicate_return_over_annotated : bool val eradicate_debug : bool val eradicate_verbose : bool -val err_file_cmdline : string val fail_on_bug : bool val failures_allowed : bool val fcp_apple_clang : string option @@ -273,6 +272,7 @@ val linter : string option val linters_def_file : string list val linters_developer_mode : bool val load_analysis_results : string option +val log_file : string option val makefile_cmdline : string val maven : bool val merge : bool @@ -285,7 +285,6 @@ val nelseg : bool val no_translate_libs : bool val objc_memory_model_on : bool val only_footprint : bool -val out_file_cmdline : string val pmd_xml : bool val precondition_stats : bool val print_active_checkers : bool diff --git a/infer/src/base/DB.ml b/infer/src/base/DB.ml index 415cfb329..b4fdfdb78 100644 --- a/infer/src/base/DB.ml +++ b/infer/src/base/DB.ml @@ -130,8 +130,7 @@ let file_modified_time ?(symlink=false) fname = let stat = (if symlink then Unix.lstat else Unix.stat) fname in stat.Unix.st_mtime with Unix.Unix_error _ -> - Logging.do_err "File %s does not exist." fname; - exit 1 + failwithf "File %s does not exist." fname let filename_create_dir fname = let dirname = Filename.dirname fname in @@ -165,8 +164,7 @@ let update_file_with_lock dir fname update = Unix.lockf fd ~mode:Unix.F_ULOCK ~len:0L; Unix.close fd ) else ( - L.err "@.save_with_lock: fail on path: %s@." path; - assert false + failwithf "save_with_lock: fail on path: %s@." path ) (** Read a file using a lock to allow write attempts in parallel. *) @@ -181,8 +179,7 @@ let read_file_with_lock dir fname = Unix.close fd; Some buf with Unix.Unix_error _ -> - L.stderr "read_file_with_lock: Unix error"; - assert false + failwith "read_file_with_lock: Unix error" with Unix.Unix_error _ -> None (** {2 Results Directory} *) diff --git a/infer/src/base/Logging.ml b/infer/src/base/Logging.ml index f6b4d4cc4..b453d688f 100644 --- a/infer/src/base/Logging.ml +++ b/infer/src/base/Logging.ml @@ -36,11 +36,11 @@ let log_dir_of_command (command : CLOpt.command) = match command with | ReportDiff -> "reportdiff" | Run -> "driver" -let stdout_err_log_files = - (((lazy F.std_formatter), (lazy Pervasives.stdout), - (lazy "out log file not initialized, stdout used instead")), - ((lazy F.err_formatter), (lazy Pervasives.stderr), - (lazy "err log file not initialized, stderr used instead"))) +let log_file = ( + lazy F.std_formatter, + lazy Pervasives.stderr, + lazy "out log file not initialized, stderr used instead" +) let close_log_file fmt chan file = (* evaluating any of the three values will evaluate the rest *) @@ -51,18 +51,14 @@ let close_log_file fmt chan file = Out_channel.close c ) -let create_log_file command name_prefix outerr = +let create_log_file command name_prefix = let log_dir = Config.results_dir ^/ Config.log_dir_name ^/ log_dir_of_command command in - let config_name = match outerr with - | `Out -> Config.out_file_cmdline - | `Err -> Config.err_file_cmdline in - let file = - (* the command-line option takes precedence if specified *) - if config_name <> "" then - config_name - else - let outerr_suffix = match outerr with `Out -> "out.log" | `Err -> "err.log" in - log_dir ^/ name_prefix ^ outerr_suffix in + let file = match Config.log_file with + | Some file -> + (* the command-line option takes precedence if specified *) + file + | None -> + log_dir ^/ name_prefix ^ ".log" in Unix.mkdir_p log_dir ; let chan = Pervasives.open_out_gen [Open_append; Open_creat] 0o666 file in let file_fmt = F.formatter_of_out_channel chan in @@ -70,10 +66,7 @@ let create_log_file command name_prefix outerr = "---- start logging from %d -------------------------------------------@." (Pid.to_int (Unix.getpid ())); if Config.print_logs then ( - let outerr_fmt = match outerr with - | `Out -> Format.std_formatter - | `Err -> Format.err_formatter in - dup_formatter file_fmt outerr_fmt + dup_formatter file_fmt Format.err_formatter ); Utils.register_epilogue (fun () -> close_log_file (lazy file_fmt) (lazy chan) (lazy file)) @@ -88,7 +81,7 @@ let should_setup_log_files (command : CLOpt.command) = match command with | Report | ReportDiff -> false -let create_outerr_log_files command prefix_opt = +let setup_log_file command prefix_opt = let lazy3 x = (lazy (fst3 (Lazy.force x)), lazy (snd3 (Lazy.force x)), lazy (trd3 (Lazy.force x))) in @@ -96,27 +89,21 @@ let create_outerr_log_files command prefix_opt = let name_prefix = match prefix_opt with | Some name -> name ^ "-" | None -> "" in - (lazy (create_log_file command name_prefix `Out) |> lazy3, - lazy (create_log_file command name_prefix `Err) |> lazy3) + lazy (create_log_file command name_prefix) |> lazy3 else - stdout_err_log_files + log_file -let ((out_formatter, out_chan, out_file), - (err_formatter, err_chan, err_file)) = - let (o_fmt, o_c, o_f), (e_fmt, e_c, e_f) = - create_outerr_log_files Config.command None in - ((ref o_fmt, ref o_c, ref o_f), - (ref e_fmt, ref e_c, ref e_f)) +let (out_formatter, out_chan, out_file) = + let (o_fmt, o_c, o_f) = setup_log_file Config.command None in + (ref o_fmt, ref o_c, ref o_f) let set_log_file_identifier command prefix_opt = - let (o_fmt, o_c, o_f), (e_fmt, e_c, e_f) = create_outerr_log_files command prefix_opt in + let (o_fmt, o_c, o_f) = setup_log_file command prefix_opt in (* close previous log files *) close_log_file !out_formatter !out_chan !out_file; - close_log_file !err_formatter !err_chan !err_file; - out_formatter := o_fmt; out_chan := o_c; out_file := o_f; - err_formatter := e_fmt; err_chan := e_c; err_file := e_f + out_formatter := o_fmt; out_chan := o_c; out_file := o_f -let log_file_names () = (Lazy.force !out_file, Lazy.force !err_file) +let log_file_name () = Lazy.force !out_file (** type of printable elements *) @@ -204,23 +191,18 @@ let out fmt_string = do_print_in_debug_or_stats_mode !out_formatter fmt_string let out_debug fmt_string = - do_print_in_debug_mode !out_formatter fmt_string + do_print_in_debug_mode !out_formatter ("PROUT: " ^^ fmt_string) let do_out fmt_string = - do_print !out_formatter fmt_string - -let err fmt_string = - do_print_in_debug_or_stats_mode !err_formatter fmt_string - -let do_err fmt_string = - do_print !err_formatter fmt_string - -let err_debug fmt_string = - do_print_in_debug_mode !err_formatter fmt_string + do_print !out_formatter ("CACA" ^^ fmt_string) let stderr = F.eprintf -let stdout = F.printf +let progress fmt_string = + if Config.quiet then F.ifprintf F.err_formatter fmt_string + else F.fprintf F.err_formatter fmt_string + +let stdout fmt_string = F.printf ("PIPI" ^^ fmt_string) (** Type of location in ml source: __POS__ *) type ml_loc = string * int * int * int @@ -247,7 +229,7 @@ let assert_false ((file, lnum, cnum, _) as ml_loc) = (** 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) + out "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) @@ -288,7 +270,7 @@ 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 + if Config.show_progress_bar && not Config.quiet then F.fprintf F.err_formatter "%s@?" text let log_progress_file () = diff --git a/infer/src/base/Logging.mli b/infer/src/base/Logging.mli index 75376ee12..0956fe5d8 100644 --- a/infer/src/base/Logging.mli +++ b/infer/src/base/Logging.mli @@ -83,23 +83,15 @@ val out : ('a, Format.formatter, unit) format -> 'a (note: only prints in debug mode) *) val out_debug : ('a, Format.formatter, unit) format -> 'a -(** print to the current error stream, as specified in set_log_file_identifier - (note: only prints in debug or stats mode) *) -val err : ('a, Format.formatter, unit) format -> 'a - -(** print to the current error stream, as specified in set_log_file_identifier - (note: only prints in debug mode) *) -val err_debug : ('a, Format.formatter, unit) format -> 'a - (** print to the current out stream, as specified in set_log_file_identifier *) val do_out : ('a, Format.formatter, unit) format -> 'a -(** print to the current err stream, as specified in set_log_file_identifier *) -val do_err : ('a, Format.formatter, unit) format -> 'a - (** print immediately to standard error *) val stderr : ('a, Format.formatter, unit) format -> 'a +(** print immediately to standard error unless --quiet is specified *) +val progress : ('a, Format.formatter, unit) format -> 'a + (** print immediately to standard output *) val stdout : ('a, Format.formatter, unit) format -> 'a @@ -161,5 +153,5 @@ val log_progress_procedure : unit -> unit (** Progress bar: log a timeout event if in developer mode. *) val log_progress_timeout_event : SymOp.failure_kind -> unit -(** Names of current temporary files for logging the output in the current executable *) -val log_file_names : unit -> string * string +(** Name of current log file *) +val log_file_name : unit -> string diff --git a/infer/src/base/Process.ml b/infer/src/base/Process.ml index ced409856..194f144c6 100644 --- a/infer/src/base/Process.ml +++ b/infer/src/base/Process.ml @@ -15,8 +15,8 @@ module F = Format found in that file, and exits, with default code 1 or a given code. *) let print_error_and_exit ?(exit_code=1) fmt = F.kfprintf (fun _ -> - L.do_err "%s" (F.flush_str_formatter ()); - let log_file = snd (L.log_file_names ()) in + L.do_out "%s" (F.flush_str_formatter ()); + let log_file = L.log_file_name () in L.stderr "@\nAn error occured. Please find details in %s@\n@\n%!" log_file; exit exit_code ) @@ -31,7 +31,7 @@ let create_process_and_wait ~prog ~args = |> function | Ok () -> () | Error err as status -> - L.stderr "Executing: %s@\n%s@\n" + L.stderr "Error executing: %s@\n%s@\n" (String.concat ~sep:" " (prog :: args)) (Unix.Exit_or_signal.to_string_hum status) ; exit (match err with `Exit_non_zero i -> i | `Signal _ -> 1) @@ -39,10 +39,10 @@ let create_process_and_wait ~prog ~args = represents, prints a message explaining the command and its status, if in debug or stats mode. It also prints a dot to show progress of jobs being finished. *) let print_status ~fail_on_failed_job f pid status = - L.err "%a%s@." + L.out "%a%s@." (fun fmt pid -> F.pp_print_string fmt (f pid)) pid (Unix.Exit_or_signal.to_string_hum status) ; - L.stdout ".%!"; + L.progress ".%!"; match status with | Error err when fail_on_failed_job -> exit (match err with `Exit_non_zero i -> i | `Signal _ -> 1) @@ -97,7 +97,7 @@ let run_jobs_in_parallel ?(fail_on_failed_job=false) jobs_stack gen_prog prog_to jobs_map done in run_job (); - L.stdout ".@."; + L.progress ".@."; L.out "Waited for %d jobs" !waited_for_jobs let pipeline ~producer_prog ~producer_args ~consumer_prog ~consumer_args = diff --git a/infer/src/base/Serialization.ml b/infer/src/base/Serialization.ml index ed26e47cf..7f80f0a8a 100644 --- a/infer/src/base/Serialization.ml +++ b/infer/src/base/Serialization.ml @@ -58,12 +58,12 @@ let create_serializer (key : Key.t) : 'a serializer = let read_data ((key': Key.t), (version': int), (value: 'a)) source_msg = if key <> key' then begin - L.err "Wrong key in when loading data from %s@\n" source_msg; + L.stderr "Wrong key in when loading data from %s@\n" source_msg; None end else if version <> version' then begin - L.err "Wrong version in when loading data from %s@\n" source_msg; + L.stderr "Wrong version in when loading data from %s@\n" source_msg; None end else Some value in diff --git a/infer/src/bufferoverrun/bufferOverrunChecker.ml b/infer/src/bufferoverrun/bufferOverrunChecker.ml index 7c52e2d1e..192166ead 100644 --- a/infer/src/bufferoverrun/bufferOverrunChecker.ml +++ b/infer/src/bufferoverrun/bufferOverrunChecker.ml @@ -93,7 +93,7 @@ struct match params with | (e, _) :: _ -> if Config.bo_debug >= 1 then - L.err "@[=== Infer Print === at %a@,%a@]%!" + L.out "@[=== Infer Print === at %a@,%a@]%!" Location.pp loc Dom.Val.pp (Sem.eval e mem loc); mem @@ -186,7 +186,7 @@ struct (Dom.Mem.add_heap field v mem, sym_num + 4) | _ -> if Config.bo_debug >= 3 then - L.err "decl_fld of unhandled type: %a@." (Typ.pp Pp.text) typ; + L.out "decl_fld of unhandled type: %a@." (Typ.pp Pp.text) typ; (mem, sym_num) in match typ.Typ.desc with @@ -215,7 +215,7 @@ struct (mem, inst_num + 1, sym_num) | _ -> if Config.bo_debug >= 3 then - L.err "declare_symbolic_parameter of unhandled type: %a@." (Typ.pp Pp.text) typ; + L.out "declare_symbolic_parameter of unhandled type: %a@." (Typ.pp Pp.text) typ; (mem, inst_num, sym_num) (* TODO: add other cases if necessary *) in List.fold ~f:add_formal ~init:(mem, inst_num, 0) (Sem.get_formals pdesc) @@ -242,13 +242,13 @@ struct = fun instr pre post -> if Config.bo_debug >= 2 then begin - L.err "@\n@\n================================@\n"; - L.err "@[Pre-state : @,%a" Dom.Mem.pp pre; - L.err "@]@\n@\n%a" (Sil.pp_instr Pp.text) instr; - L.err "@\n@\n"; - L.err "@[Post-state : @,%a" Dom.Mem.pp post; - L.err "@]@\n"; - L.err "================================@\n@." + L.out "@\n@\n================================@\n"; + L.out "@[Pre-state : @,%a" Dom.Mem.pp pre; + L.out "@]@\n@\n%a" (Sil.pp_instr Pp.text) instr; + L.out "@\n@\n"; + L.out "@[Post-state : @,%a" Dom.Mem.pp post; + L.out "@]@\n"; + L.out "================================@\n@." end let exec_instr @@ -341,10 +341,10 @@ struct let offset = ArrayBlk.offsetof arr in let idx = (if is_plus then Itv.plus else Itv.minus) offset idx in (if Config.bo_debug >= 2 then - (L.err "@[Add condition :@,"; - L.err "array: %a@," ArrayBlk.pp arr; - L.err " idx: %a@," Itv.pp idx; - L.err "@]@.")); + (L.out "@[Add condition :@,"; + L.out "array: %a@," ArrayBlk.pp arr; + L.out " idx: %a@," Itv.pp idx; + L.out "@]@.")); if size <> Itv.bot && idx <> Itv.bot then Dom.ConditionSet.add_bo_safety pname loc site ~size ~idx cond_set else cond_set @@ -368,12 +368,12 @@ struct let print_debug_info : Sil.instr -> Dom.Mem.astate -> Dom.ConditionSet.t -> unit = fun instr pre cond_set -> if Config.bo_debug >= 2 then - (L.err "@\n@\n================================@\n"; - L.err "@[Pre-state : @,%a" Dom.Mem.pp pre; - L.err "@]@\n@\n%a" (Sil.pp_instr Pp.text) instr; - L.err "@[@\n@\n%a" Dom.ConditionSet.pp cond_set; - L.err "@]@\n"; - L.err "================================@\n@.") + (L.out "@\n@\n================================@\n"; + L.out "@[Pre-state : @,%a" Dom.Mem.pp pre; + L.out "@]@\n@\n%a" (Sil.pp_instr Pp.text) instr; + L.out "@[@\n@\n%a" Dom.ConditionSet.pp cond_set; + L.out "@]@\n"; + L.out "================================@\n@.") let collect_instr : extras ProcData.t -> CFG.node -> Dom.ConditionSet.t * Dom.Mem.astate @@ -467,7 +467,7 @@ let compute_post let print_summary : Typ.Procname.t -> Dom.Summary.t -> unit = fun proc_name s -> - L.err "@\n@[Summary of %a :@,%a@]@." + L.out "@\n@[Summary of %a :@,%a@]@." Typ.Procname.pp proc_name Dom.Summary.pp_summary s diff --git a/infer/src/bufferoverrun/bufferOverrunDomain.ml b/infer/src/bufferoverrun/bufferOverrunDomain.ml index a82095be3..efc1062c7 100644 --- a/infer/src/bufferoverrun/bufferOverrunDomain.ml +++ b/infer/src/bufferoverrun/bufferOverrunDomain.ml @@ -670,7 +670,7 @@ struct else let () = if Config.bo_debug >= 3 then - L.err "Weak update for %a <- %a@." PowLoc.pp ploc Val.pp v + L.out "Weak update for %a <- %a@." PowLoc.pp ploc Val.pp v in weak_update_heap ploc v s end diff --git a/infer/src/clang/CType.ml b/infer/src/clang/CType.ml index 68a39360c..37891499d 100644 --- a/infer/src/clang/CType.ml +++ b/infer/src/clang/CType.ml @@ -45,11 +45,11 @@ let rec return_type_of_function_qual_type (qual_type : Clang_ast_t.qual_type) = | Some BlockPointerType (_, in_qual) -> return_type_of_function_qual_type in_qual | Some _ -> - Logging.err_debug "Warning: Type pointer %s is not a function type." + L.out_debug "Warning: Type pointer %s is not a function type." (Clang_ast_extend.type_ptr_to_string qual_type.qt_type_ptr); {qual_type with qt_type_ptr=Clang_ast_extend.ErrorType} | None -> - Logging.err_debug "Warning: Type pointer %s not found." + L.out_debug "Warning: Type pointer %s not found." (Clang_ast_extend.type_ptr_to_string qual_type.qt_type_ptr); {qual_type with qt_type_ptr=Clang_ast_extend.ErrorType} diff --git a/infer/src/clang/Capture.re b/infer/src/clang/Capture.re index 8a8d72f9d..ce2e799ed 100644 --- a/infer/src/clang/Capture.re +++ b/infer/src/clang/Capture.re @@ -22,8 +22,7 @@ let catch_biniou_buffer_errors f x => /* suppress warning: allow this one case because we're just reraising the error with another error message so it doesn't really matter if this eventually fails */ | Invalid_argument "Bi_inbuf.refill_from_channel" => - Logging.err "WARNING: biniou buffer too short, skipping the file@\n"; - assert false + failwith "WARNING: biniou buffer too short, skipping the file" } ) [@warning "-52"]; diff --git a/infer/src/clang/cFrontend_checkers_main.ml b/infer/src/clang/cFrontend_checkers_main.ml index bcc5b0e87..affab2e4a 100644 --- a/infer/src/clang/cFrontend_checkers_main.ml +++ b/infer/src/clang/cFrontend_checkers_main.ml @@ -277,8 +277,8 @@ let do_frontend_checks (trans_unit_ctx: CFrontend_config.translation_unit_contex store_issues source_file; Logging.out "End linting file %a@\n" SourceFile.pp source_file; CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file; - | _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *) + | _ -> assert false (* NOTE: Assumes that an AST always starts with a TranslationUnitDecl *) with | Assert_failure (file, line, column) as exn -> - Logging.err "Fatal error: exception Assert_failure(%s, %d, %d)@\n%!" file line column; + Logging.stderr "Fatal error: exception Assert_failure(%s, %d, %d)@\n%!" file line column; raise exn diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index e6735a13a..37d678cd9 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -82,8 +82,7 @@ let evaluate_place_holder ph an = | "%iphoneos_target_sdk_version%" -> MF.monospaced_to_string (CFrontend_checkers.iphoneos_target_sdk_version an) | "%available_ios_sdk%" -> MF.monospaced_to_string (CFrontend_checkers.available_ios_sdk an) - | _ -> (Logging.err "ERROR: helper function %s is unknown. Stop.\n" ph; - assert false) + | _ -> failwithf "Helper function %s is unknown" ph (* given a message this function searches for a place-holder identifier, eg %id%. Then it evaluates id and replaces %id% in message @@ -114,16 +113,13 @@ let string_to_err_kind = function | "ERROR" -> Exceptions.Kerror | "INFO" -> Exceptions.Kinfo | "ADVICE" -> Exceptions.Kadvice - | s -> (Logging.err "\n[ERROR] Severity %s does not exist. Stop.\n" s; - assert false) + | s -> failwithf "Severity %s does not exist" s let string_to_issue_mode m = match m with | "ON" -> CIssue.On | "OFF" -> CIssue.Off - | s -> - (Logging.err "\n[ERROR] Mode %s does not exist. Please specify ON/OFF\n" s; - assert false) + | s -> failwithf "Mode %s does not exist. Please specify ON/OFF" s (** Convert a parsed checker in list of linters *) let create_parsed_linters linters_def_file checkers : linter list = @@ -194,10 +190,7 @@ let rec apply_substitution f sub = let expand_formula phi _map _error_msg = let fail_with_circular_macro_definition name error_msg = - Logging.out - "[ERROR]: Macro '%s' has a circular definition.\n Cycle:\n%s" - name error_msg; - failwith ("Cannot expand....\n") in + failwithf "Macro '%s' has a circular definition.\n Cycle:\n%s" name error_msg in let open CTL in let rec expand acc map error_msg = match acc with diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index f9d3de86e..aec4d4624 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -880,8 +880,7 @@ struct if Int.equal (List.length params) (List.length params_stmt) then params else - (Logging.out_debug "ERROR: stmt_list and res_trans_par.exps must have same size\n"; - assert false) in + failwith "ERROR: stmt_list and res_trans_par.exps must have same size" in let act_params = if is_cf_retain_release then (Exp.Const (Const.Cint IntLit.one), Typ.mk (Tint Typ.IBool)) :: act_params else act_params in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 35d3a3c3d..637b5dd0e 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -23,7 +23,7 @@ exception TemplatedCodeException of Clang_ast_t.stmt let extract_item_from_singleton l warning_string failure_val = match l with | [item] -> item - | _ -> Logging.err_debug "%s" warning_string; failure_val + | _ -> L.out_debug "%s" warning_string; failure_val let dummy_exp = (Exp.minus_one, Typ.mk (Tint Typ.IInt)) @@ -442,7 +442,7 @@ let cast_operation trans_state cast_kind exps cast_typ sil_loc is_objc_bridged = if Exp.is_zero exp then ([], (Exp.null, cast_typ)) else ([], (exp, cast_typ)) | _ -> - Logging.err_debug + L.out_debug "\nWARNING: Missing translation for Cast Kind %s. The construct has been ignored...\n" (Clang_ast_j.string_of_cast_kind cast_kind); ([], (exp, cast_typ)) @@ -572,8 +572,7 @@ let rec get_type_from_exp_stmt stmt = get_type_from_exp_stmt (extract_stmt_from_singleton stmt_list "WARNING: We expect only one stmt.") | DeclRefExpr(_, _, _, info) -> do_decl_ref_exp info | _ -> - Logging.err_debug "Failing with: %s@\n%!" (Clang_ast_j.string_of_stmt stmt); - assert false + failwithf "Cannot get type fo stmt %s" (Clang_ast_j.string_of_stmt stmt) module Self = struct @@ -749,7 +748,7 @@ let var_or_zero_in_init_list tenv e typ ~return_zero:return_zero = let extract_item_from_option op warning_string = match op with | Some item -> item - | _ -> Logging.err_debug warning_string; assert false + | _ -> L.out_debug warning_string; assert false let extract_id_from_singleton id_list warning_string = extract_item_from_singleton id_list warning_string (dummy_id ()) diff --git a/infer/src/clang/cType_to_sil_type.ml b/infer/src/clang/cType_to_sil_type.ml index 6940247e4..8d3fcc145 100644 --- a/infer/src/clang/cType_to_sil_type.ml +++ b/infer/src/clang/cType_to_sil_type.ml @@ -9,6 +9,8 @@ open! IStd +module L = Logging + let get_builtin_objc_typename builtin_type = match builtin_type with | `ObjCId -> Typ.Name.C.from_string CFrontend_config.objc_object @@ -145,11 +147,11 @@ and decl_ptr_to_type_desc translate_decl tenv decl_ptr : Typ.desc = | Some (ObjCCategoryImplDecl _ as d) | Some (EnumDecl _ as d) -> translate_decl tenv d | Some _ -> - Logging.err_debug "Warning: Wrong decl found for pointer %s " + L.out_debug "Warning: Wrong decl found for pointer %s " (Clang_ast_j.string_of_pointer decl_ptr); Typ.Tvoid | None -> - Logging.err_debug "Warning: Decl pointer %s not found." + L.out_debug "Warning: Decl pointer %s not found." (Clang_ast_j.string_of_pointer decl_ptr); Typ.Tvoid diff --git a/infer/src/eradicate/AnnotatedSignature.ml b/infer/src/eradicate/AnnotatedSignature.ml index a0c2928a5..1aa80c3f6 100644 --- a/infer/src/eradicate/AnnotatedSignature.ml +++ b/infer/src/eradicate/AnnotatedSignature.ml @@ -118,10 +118,10 @@ let mark proc_name ann asig (b, bs) = (s, ia', t) in let params' = let fail () = - L.stdout + L.stderr "INTERNAL ERROR: annotation for procedure %s has wrong number of arguments@." (Typ.Procname.to_unique_id proc_name); - L.stdout " ANNOTATED SIGNATURE: %a@." (pp proc_name) asig; + L.stderr " ANNOTATED SIGNATURE: %a@." (pp proc_name) asig; assert false in let rec combine l1 l2 = match l1, l2 with | (p, ia, t):: l1', l2' when String.equal (Mangled.to_string p) "this" -> diff --git a/infer/src/harness/inhabit.ml b/infer/src/harness/inhabit.ml index 483e038bd..fe007eeb7 100644 --- a/infer/src/harness/inhabit.ml +++ b/infer/src/harness/inhabit.ml @@ -142,8 +142,7 @@ let rec inhabit_typ tenv typ cfg env = | Typ.Tint (_) -> (Exp.Const (Const.Cint (IntLit.zero)), env) | Typ.Tfloat (_) -> (Exp.Const (Const.Cfloat 0.0), env) | _ -> - L.err "Couldn't inhabit typ: %a@." (Typ.pp Pp.text) typ; - assert false in + failwithf "Couldn't inhabit typ: %a" (Typ.pp Pp.text) typ in let (inhabited_exp, env') = inhabit_internal typ { env with cur_inhabiting = TypSet.add typ env.cur_inhabiting } in (inhabited_exp, { env' with cache = TypMap.add typ inhabited_exp env.cache; @@ -193,10 +192,9 @@ let inhabit_call tenv (procname, receiver) cfg env = | ((name, _) :: formals, Some receiver) -> (name, receiver) :: formals | (formals, None) -> formals | ([], Some _) -> - L.err - "Expected at least one formal to bind receiver to in method %a@." - Typ.Procname.pp procname; - assert false in + failwithf + "Expected at least one formal to bind receiver to in method %a" + Typ.Procname.pp procname in let (args, env) = inhabit_args tenv formals cfg env in inhabit_call_with_args procname procdesc args env | None -> env diff --git a/infer/src/integration/CaptureCompilationDatabase.ml b/infer/src/integration/CaptureCompilationDatabase.ml index 898c86fad..ec68282f7 100644 --- a/infer/src/integration/CaptureCompilationDatabase.ml +++ b/infer/src/integration/CaptureCompilationDatabase.ml @@ -64,7 +64,7 @@ let run_compilation_file compilation_database file = let run_compilation_database compilation_database should_capture_file = let number_of_files = CompilationDatabase.get_size compilation_database in Logging.out "Starting %s %d files \n%!" capture_text number_of_files; - Logging.stdout "Starting %s %d files \n%!" capture_text number_of_files; + Logging.progress "Starting %s %d files \n%!" capture_text number_of_files; let jobs_stack = create_files_stack compilation_database should_capture_file in let capture_text_upper = String.capitalize capture_text in let job_to_string = diff --git a/infer/src/java/jFrontend.ml b/infer/src/java/jFrontend.ml index 0881100b3..02616007d 100644 --- a/infer/src/java/jFrontend.ml +++ b/infer/src/java/jFrontend.ml @@ -161,7 +161,7 @@ let create_icfg source_file linereader program icfg cn node = end; Cg.add_defined_node icfg.JContext.cg proc_name with JBasics.Class_structure_error _ -> - L.do_err + L.stderr "create_icfg raised JBasics.Class_structure_error on %a@." Typ.Procname.pp proc_name in Javalib.m_iter translate node diff --git a/infer/src/java/jTrans.ml b/infer/src/java/jTrans.ml index e9a2067cc..1ebcf810a 100644 --- a/infer/src/java/jTrans.ml +++ b/infer/src/java/jTrans.ml @@ -115,7 +115,7 @@ let get_field_name program static tenv cn fs = fieldname | None -> (* TODO: understand why fields cannot be found here *) - L.do_err "cannot find %s.%s@." (JBasics.cn_name cn) (JBasics.fs_name fs); + L.stderr "cannot find %s.%s@." (JBasics.cn_name cn) (JBasics.fs_name fs); raise (Frontend_error "Cannot find fieldname") @@ -380,7 +380,7 @@ let create_cm_procdesc source_file program linereader icfg cm proc_name = procdesc in Some (procdesc, bytecode, jbir_code) with JBir.Subroutine -> - L.do_err + L.stderr "create_procdesc raised JBir.Subroutine on %a@." Typ.Procname.pp proc_name; None @@ -1057,5 +1057,5 @@ let rec instruction (context : JContext.t) pc instr : translation = | _ -> Skip with Frontend_error s -> - L.do_err "Skipping because of: %s@." s; + L.stderr "Skipping because of: %s@." s; Skip