From 32b2a707e86610cd1e569ced4ea2257ab3271331 Mon Sep 17 00:00:00 2001 From: Varun Arora Date: Wed, 28 Feb 2018 04:46:13 -0800 Subject: [PATCH] [reporting] Exceptions of visibility Exn_developer are now logged using EventLogger when not running in developer mode Reviewed By: dulmarod Differential Revision: D7082468 fbshipit-source-id: 410d560 --- infer/src/IR/Errlog.ml | 24 ++++++++++++++++++------ infer/src/IR/Errlog.mli | 4 ++-- infer/src/backend/reporting.ml | 15 ++++++++------- infer/src/backend/reporting.mli | 2 +- infer/src/base/CommandLineOption.ml | 2 +- infer/src/base/Config.ml | 3 ++- infer/src/base/EventLogger.ml | 29 +++++++++++++++++++++++++++++ infer/src/base/EventLogger.mli | 9 +++++++++ infer/src/clang/cFrontend_errors.ml | 14 +++++--------- 9 files changed, 75 insertions(+), 27 deletions(-) diff --git a/infer/src/IR/Errlog.ml b/infer/src/IR/Errlog.ml index 0c9e97545..4779ccf72 100644 --- a/infer/src/IR/Errlog.ml +++ b/infer/src/IR/Errlog.ml @@ -234,8 +234,8 @@ let update errlog_old errlog_new = ErrLogHash.iter (fun err_key l -> ignore (add_issue errlog_old err_key l)) errlog_new -let log_issue err_kind err_log loc (node_id, node_key) session ltr ?linters_def_file ?doc_url - ?access exn = +let log_issue procname err_kind err_log loc (node_id, node_key) session ltr ?linters_def_file + ?doc_url ?access exn = let error = Exceptions.recognize_exception exn in let err_kind = match error.kind with Some err_kind -> err_kind | _ -> err_kind in let hide_java_loc_zero = @@ -249,12 +249,24 @@ let log_issue err_kind err_log loc (node_id, node_key) session ltr ?linters_def_ | _ -> false in - let log_it = + let exn_developer = Exceptions.equal_visibility error.visibility Exceptions.Exn_developer in + let should_report = Exceptions.equal_visibility error.visibility Exceptions.Exn_user - || Config.developer_mode - && Exceptions.equal_visibility error.visibility Exceptions.Exn_developer + || Config.developer_mode && exn_developer in - if log_it && not hide_java_loc_zero && not hide_memory_error then + ( if exn_developer then + let issue = + EventLogger.AnalysisIssue + (* TODO: Add clang_method_kind field (T26423401) *) + { bug_type= error.name.IssueType.unique_id + ; bug_kind= Exceptions.err_kind_string err_kind + ; exception_triggered_location= Option.map ~f:Logging.ml_loc_to_string error.ml_loc + ; lang= Typ.Procname.get_language procname |> Language.to_explicit_string + ; procedure_name= Typ.Procname.to_string procname + ; source_location= loc } + in + EventLogger.log issue ) ; + if should_report && not hide_java_loc_zero && not hide_memory_error then let added = let node_id_key = {node_id; node_key} in let err_data = diff --git a/infer/src/IR/Errlog.mli b/infer/src/IR/Errlog.mli index e61368dab..7559820d1 100644 --- a/infer/src/IR/Errlog.mli +++ b/infer/src/IR/Errlog.mli @@ -93,5 +93,5 @@ val update : t -> t -> unit (** Update an old error log with a new one *) val log_issue : - Exceptions.err_kind -> t -> Location.t -> int * Caml.Digest.t -> int -> loc_trace - -> ?linters_def_file:string -> ?doc_url:string -> ?access:string -> exn -> unit + Typ.Procname.t -> Exceptions.err_kind -> t -> Location.t -> int * Caml.Digest.t -> int + -> loc_trace -> ?linters_def_file:string -> ?doc_url:string -> ?access:string -> exn -> unit diff --git a/infer/src/backend/reporting.ml b/infer/src/backend/reporting.ml index 3d45d45ad..2963b0772 100644 --- a/infer/src/backend/reporting.ml +++ b/infer/src/backend/reporting.ml @@ -16,8 +16,8 @@ type log_t = type log_issue_from_errlog = Errlog.t -> log_t -let log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url - ?access exn = +let log_issue_from_errlog procname err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file + ?doc_url ?access exn = let issue_type = (Exceptions.recognize_exception exn).name in if not Config.filtering (* no-filtering takes priority *) || issue_type.IssueType.enabled then let loc = match loc with None -> State.get_loc () | Some loc -> loc in @@ -32,14 +32,15 @@ let log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_ match session with None -> (State.get_session () :> int) | Some session -> session in let ltr = match ltr with None -> State.get_loc_trace () | Some ltr -> ltr in - Errlog.log_issue err_kind err_log loc node_id session ltr ?linters_def_file ?doc_url ?access - exn + Errlog.log_issue procname err_kind err_log loc node_id session ltr ?linters_def_file ?doc_url + ?access exn let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url ?access exn = + let procname = Specs.get_proc_name summary in let is_java_generated_method = - match Specs.get_proc_name summary with + match procname with | Typ.Procname.Java java_pname -> Typ.Procname.Java.is_generated java_pname | _ -> @@ -53,8 +54,8 @@ let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters if should_suppress_lint || is_java_generated_method then () (* Skip the reporting *) else let err_log = Specs.get_err_log summary in - log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url - ?access exn + log_issue_from_errlog procname err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file + ?doc_url ?access exn let log_issue_deprecated ?(store_summary= false) err_kind proc_name ?loc ?node_id ?session ?ltr diff --git a/infer/src/backend/reporting.mli b/infer/src/backend/reporting.mli index fbaa04ed4..d208694f9 100644 --- a/infer/src/backend/reporting.mli +++ b/infer/src/backend/reporting.mli @@ -32,7 +32,7 @@ val log_info_deprecated : ?store_summary:bool -> Typ.Procname.t -> log_t DEPRECATED as it can create race conditions between checkers. Use log_info instead *) -val log_issue_from_errlog : Exceptions.err_kind -> log_issue_from_errlog +val log_issue_from_errlog : Typ.Procname.t -> Exceptions.err_kind -> log_issue_from_errlog (** Report an issue of a given kind in the given error log. *) val log_error : Specs.summary -> log_t diff --git a/infer/src/base/CommandLineOption.ml b/infer/src/base/CommandLineOption.ml index dec36671b..4f8f96a01 100644 --- a/infer/src/base/CommandLineOption.ml +++ b/infer/src/base/CommandLineOption.ml @@ -271,7 +271,7 @@ let mk ?(deprecated= []) ?(parse_mode= InferCommand) ?(in_help= []) ~long ?short let closure = mk_setter variable in let setter str = try closure str with exc -> - raise (Arg.Bad ("bad value " ^ str ^ " for flag " ^ long ^ " (" ^ Exn.to_string exc ^ ")")) + raise (Arg.Bad (F.sprintf "bad value %s for flag %s (%s)" str long (Exn.to_string exc))) in let spec = mk_spec setter in let doc = diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 459ffc3b8..7cb22fe7e 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -596,7 +596,8 @@ and ( analysis_blacklist_files_containing_options let var = CLOpt.mk_string_list ~deprecated ~long ~meta ~f:mirror "" in match source_of_truth with | Some var -> - (* if the analyzer already has a variable associated to it, use it *) var + (* if the analyzer already has a variable associated to it, use it *) + var | None -> (* record the variable associated to the analyzer if this is the first time we see this analyzer *) diff --git a/infer/src/base/EventLogger.ml b/infer/src/base/EventLogger.ml index f1bbce7ed..f2ad846f1 100644 --- a/infer/src/base/EventLogger.ml +++ b/infer/src/base/EventLogger.ml @@ -71,6 +71,30 @@ end = struct new_id end +type analysis_issue = + { bug_kind: string + ; bug_type: string + ; exception_triggered_location: string option + ; lang: string + ; procedure_name: string + ; source_location: Location.t } + +let create_analysis_issue_row base record = + let open JsonBuilder in + base |> add_string ~key:"bug_kind" ~data:record.bug_kind + |> add_string ~key:"bug_type" ~data:record.bug_type + |> add_string_opt ~key:"exception_triggered_location" ~data:record.exception_triggered_location + |> add_string ~key:"lang" ~data:record.lang + |> add_string ~key:"procedure_name" ~data:record.procedure_name + |> add_string ~key:"source_location" + ~data: + (String.concat + [ string_of_int record.source_location.line + ; ":" + ; string_of_int record.source_location.col ]) + |> add_string ~key:"source_file" ~data:(SourceFile.to_rel_path record.source_location.file) + + type analysis_stats = { analysis_nodes_visited: int ; analysis_status: SymOp.failure_kind option @@ -175,6 +199,7 @@ let create_procedures_translated_row base record = type event = + | AnalysisIssue of analysis_issue | AnalysisStats of analysis_stats | CallTrace of call_trace | FrontendException of frontend_exception @@ -183,6 +208,8 @@ type event = let string_of_event event = match event with + | AnalysisIssue _ -> + "AnalysisIssue" | AnalysisStats _ -> "AnalysisStats" | CallTrace _ -> @@ -236,6 +263,8 @@ module LoggerImpl : S = struct |> add_int ~key:"time" ~data:(int_of_float (Unix.time ())) in ( match event with + | AnalysisIssue record -> + create_analysis_issue_row base record | AnalysisStats record -> create_analysis_stats_row base record | CallTrace record -> diff --git a/infer/src/base/EventLogger.mli b/infer/src/base/EventLogger.mli index 6d3245a49..3e723a128 100644 --- a/infer/src/base/EventLogger.mli +++ b/infer/src/base/EventLogger.mli @@ -7,6 +7,14 @@ * of patent rights can be found in the PATENTS file in the same directory. *) +type analysis_issue = + { bug_kind: string + ; bug_type: string + ; exception_triggered_location: string option + ; lang: string + ; procedure_name: string + ; source_location: Location.t } + type analysis_stats = { analysis_nodes_visited: int ; analysis_status: SymOp.failure_kind option @@ -42,6 +50,7 @@ type procedures_translated = ; source_file: SourceFile.t } type event = + | AnalysisIssue of analysis_issue | AnalysisStats of analysis_stats | CallTrace of call_trace | FrontendException of frontend_exception diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index bea13c340..31ce8fad6 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -433,7 +433,9 @@ let expand_checkers macro_map path_map checkers = List.map ~f:expand_one_checker checkers -let get_err_log translation_unit_context method_decl_opt = +(** Add a frontend warning with a description desc at location loc to the errlog of a proc desc *) +let log_frontend_issue translation_unit_context method_decl_opt (node: Ctl_parser_types.ast_node) + (issue_desc: CIssue.issue_desc) linters_def_file = let procname = match method_decl_opt with | Some method_decl -> @@ -441,13 +443,7 @@ let get_err_log translation_unit_context method_decl_opt = | None -> Typ.Procname.Linters_dummy_method in - LintIssues.get_err_log procname - - -(** Add a frontend warning with a description desc at location loc to the errlog of a proc desc *) -let log_frontend_issue translation_unit_context method_decl_opt (node: Ctl_parser_types.ast_node) - (issue_desc: CIssue.issue_desc) linters_def_file = - let errlog = get_err_log translation_unit_context method_decl_opt in + let errlog = LintIssues.get_err_log procname in let err_desc = Errdesc.explain_frontend_warning issue_desc.description issue_desc.suggestion issue_desc.loc in @@ -462,7 +458,7 @@ let log_frontend_issue translation_unit_context method_decl_opt (node: Ctl_parse CAst_utils.generate_key_stmt st in let key = Utils.better_hash key_str in - Reporting.log_issue_from_errlog err_kind errlog exn ~loc:issue_desc.loc ~ltr:trace + Reporting.log_issue_from_errlog procname err_kind errlog exn ~loc:issue_desc.loc ~ltr:trace ~node_id:(0, key) ?linters_def_file ?doc_url:issue_desc.doc_url