[ConfigImpact] Print config-impact-report.json

Summary:
The config impact checker prints ungated callees in a separate file config-impact-report.json,
because its results should be compared before actual reporting as the cost checker does.

Reviewed By: ezgicicek

Differential Revision: D26665097

fbshipit-source-id: 0c6e13403
master
Sungkeun Cho 4 years ago committed by Facebook GitHub Bot
parent 91015609b2
commit 11e3acb20e

@ -147,3 +147,13 @@ type cost_item = {
}
type costs_report = cost_item list
type config_impact_item = {
hash : string;
loc : loc;
procedure_name : string;
procedure_id : string;
unchecked_callees : string;
}
type config_impact_report = config_impact_item list

@ -124,10 +124,18 @@ let pp_html source fmt summary =
module ReportSummary = struct
type t = {loc: Location.t; cost_opt: CostDomain.summary option; err_log: Errlog.t}
type t =
{ loc: Location.t
; cost_opt: CostDomain.summary option
; config_impact_opt: ConfigImpactAnalysis.Summary.t option
; err_log: Errlog.t }
let of_full_summary (f : full_summary) =
({loc= get_loc f; cost_opt= f.payloads.Payloads.cost; err_log= f.err_log} : t)
( { loc= get_loc f
; cost_opt= f.payloads.Payloads.cost
; config_impact_opt= f.payloads.Payloads.config_impact_analysis
; err_log= f.err_log }
: t )
module SQLite = SqliteUtils.MarshalledDataNOTForComparison (struct
@ -333,10 +341,10 @@ module OnDisk = struct
~f:(fun stmt ->
let proc_name = Sqlite3.column stmt 0 |> Procname.SQLite.deserialize in
if filter dummy_source_file proc_name then
let ({loc; cost_opt; err_log} : ReportSummary.t) =
let ({loc; cost_opt; config_impact_opt; err_log} : ReportSummary.t) =
Sqlite3.column stmt 1 |> ReportSummary.SQLite.deserialize
in
f proc_name loc cost_opt err_log )
f proc_name loc cost_opt config_impact_opt err_log )
let make_filtered_iterator_from_config ~iter ~f =

@ -87,7 +87,14 @@ module OnDisk : sig
(** Iterates over all stored summaries *)
val iter_report_summaries_from_config :
f:(Procname.t -> Location.t -> CostDomain.summary option -> Errlog.t -> unit) -> unit
f:
( Procname.t
-> Location.t
-> CostDomain.summary option
-> ConfigImpactAnalysis.Summary.t option
-> Errlog.t
-> unit)
-> unit
(** Iterates over all analysis artefacts listed above, for each procedure *)
val pp_specs_from_config : Format.formatter -> unit

@ -26,6 +26,7 @@ type id =
| PerfEvents
| ProcnamesLocks
| RacerDIssues
| ReportConfigImpactJson
| ReportCostsJson
| ReportHtml
| ReportJson
@ -133,6 +134,11 @@ let of_id = function
; kind= IssuesDirectory
; before_incremental_analysis= Delete
; before_caching_capture= Delete }
| ReportConfigImpactJson ->
{ rel_path= "config-impact-report.json"
; kind= File
; before_incremental_analysis= Delete
; before_caching_capture= Delete }
| ReportCostsJson ->
{ rel_path= "costs-report.json"
; kind= File

@ -27,6 +27,7 @@ type id =
| ProcnamesLocks
(** directory of per-{!Procname.t} file locks, used by the analysis scheduler in certain modes *)
| RacerDIssues (** directory of issues reported by the RacerD analysis *)
| ReportConfigImpactJson (** reports of the config impact analysis *)
| ReportCostsJson (** reports of the costs analysis *)
| ReportHtml (** directory of the HTML report *)
| ReportJson (** the main product of the analysis: [report.json] *)

@ -84,6 +84,9 @@ module UncheckedCallees = struct
let replace_location_by_call location x =
map (UncheckedCallee.replace_location_by_call location) x
let encode astate = Marshal.to_string astate [] |> Base64.encode_exn
end
module Loc = struct
@ -130,6 +133,9 @@ module Summary = struct
let pp f {unchecked_callees; has_call_stmt} =
F.fprintf f "@[unchecked callees:@,%a,has_call_stmt:%b@]" UncheckedCallees.pp unchecked_callees
has_call_stmt
let get_unchecked_callees {unchecked_callees} = unchecked_callees
end
module Dom = struct

@ -7,10 +7,18 @@
open! IStd
module UncheckedCallees : sig
type t
val encode : t -> string
end
module Summary : sig
type t
val pp : Format.formatter -> t -> unit
val get_unchecked_callees : t -> UncheckedCallees.t
end
val checker : Summary.t InterproceduralAnalysis.t -> Summary.t option

@ -184,7 +184,9 @@ let execute_analyze_json () =
let report ?(suppress_console = false) () =
let issues_json = ResultsDir.get_path ReportJson in
JsonReports.write_reports ~issues_json ~costs_json:(ResultsDir.get_path ReportCostsJson) ;
let costs_json = ResultsDir.get_path ReportCostsJson in
let config_impact_json = ResultsDir.get_path ReportConfigImpactJson in
JsonReports.write_reports ~issues_json ~costs_json ~config_impact_json ;
(* Post-process the report according to the user config. By default, calls report.py to create a
human-readable report.

@ -304,6 +304,27 @@ end
module JsonCostsPrinter = MakeJsonListPrinter (JsonCostsPrinterElt)
module JsonConfigImpactPrinterElt = struct
type elt =
{ loc: Location.t
; proc_name: Procname.t
; config_impact_opt: ConfigImpactAnalysis.Summary.t option }
let to_string {loc; proc_name; config_impact_opt} =
Option.map config_impact_opt ~f:(fun config_impact ->
let {NoQualifierHashProcInfo.hash; loc; procedure_name; procedure_id} =
NoQualifierHashProcInfo.get loc proc_name
in
let unchecked_callees =
ConfigImpactAnalysis.Summary.get_unchecked_callees config_impact
|> ConfigImpactAnalysis.UncheckedCallees.encode
in
Jsonbug_j.string_of_config_impact_item
{Jsonbug_t.hash; loc; procedure_name; procedure_id; unchecked_callees} )
end
module JsonConfigImpactPrinter = MakeJsonListPrinter (JsonConfigImpactPrinterElt)
let mk_error_filter filters proc_name file error_name =
(Config.write_html || not (IssueType.(equal skip_function) error_name))
&& filters.Inferconfig.path_filter file
@ -322,24 +343,34 @@ let write_costs proc_name loc cost_opt (outfile : Utils.outfile) =
JsonCostsPrinter.pp outfile.fmt {loc; proc_name; cost_opt}
let write_config_impact proc_name loc config_impact_opt (outfile : Utils.outfile) =
if ExternalConfigImpactData.is_in_config_data_file proc_name then
JsonConfigImpactPrinter.pp outfile.fmt {loc; proc_name; config_impact_opt}
(** Process lint issues of a procedure *)
let write_lint_issues filters (issues_outf : Utils.outfile) linereader procname error_log =
let error_filter = mk_error_filter filters procname in
IssuesJson.pp_issues_of_error_log issues_outf.fmt error_filter linereader None procname error_log
(** Process a summary *)
let process_summary proc_name loc ~cost:(cost_opt, costs_outf) err_log issues_acc =
let process_summary proc_name loc ~cost:(cost_opt, costs_outf)
~config_impact:(config_impact_opt, config_impact_outf) err_log issues_acc =
write_costs proc_name loc cost_opt costs_outf ;
write_config_impact proc_name loc config_impact_opt config_impact_outf ;
collect_issues proc_name loc err_log issues_acc
let process_all_summaries_and_issues ~issues_outf ~costs_outf =
let process_all_summaries_and_issues ~issues_outf ~costs_outf ~config_impact_outf =
let linereader = LineReader.create () in
let filters = Inferconfig.create_filters () in
let all_issues = ref [] in
Summary.OnDisk.iter_report_summaries_from_config ~f:(fun proc_name loc cost_opt err_log ->
all_issues := process_summary proc_name loc ~cost:(cost_opt, costs_outf) err_log !all_issues ) ;
Summary.OnDisk.iter_report_summaries_from_config
~f:(fun proc_name loc cost_opt config_impact_opt err_log ->
all_issues :=
process_summary proc_name loc ~cost:(cost_opt, costs_outf)
~config_impact:(config_impact_opt, config_impact_outf)
err_log !all_issues ) ;
all_issues := Issue.sort_filter_issues !all_issues ;
List.iter
~f:(fun {Issue.proc_name; proc_location; err_key; err_data} ->
@ -353,7 +384,7 @@ let process_all_summaries_and_issues ~issues_outf ~costs_outf =
()
let write_reports ~issues_json ~costs_json =
let write_reports ~issues_json ~costs_json ~config_impact_json =
let mk_outfile fname =
match Utils.create_outfile fname with
| None ->
@ -372,6 +403,8 @@ let write_reports ~issues_json ~costs_json =
in
let issues_outf = open_outfile_and_fmt issues_json in
let costs_outf = open_outfile_and_fmt costs_json in
process_all_summaries_and_issues ~issues_outf ~costs_outf ;
let config_impact_outf = open_outfile_and_fmt config_impact_json in
process_all_summaries_and_issues ~issues_outf ~costs_outf ~config_impact_outf ;
close_fmt_and_outfile config_impact_outf ;
close_fmt_and_outfile costs_outf ;
close_fmt_and_outfile issues_outf

@ -14,4 +14,4 @@ val loc_trace_to_jsonbug_record :
val censored_reason : IssueType.t -> SourceFile.t -> string option
val write_reports : issues_json:string -> costs_json:string -> unit
val write_reports : issues_json:string -> costs_json:string -> config_impact_json:string -> unit

@ -16,9 +16,9 @@ let library =
(flags
(:standard
-open Core -open IStdlib -open IStd -open OpenSource -open ATDGenerated
-open IBase -open IR -open Absint -open BO -open Costlib -open Concurrency -open Backend
-open IBase -open IR -open Absint -open BO -open Checkers -open Costlib -open Concurrency -open Backend
-open TestDeterminators -open ClangFrontend -open ASTLanguage -open JavaFrontend %s %s))
(libraries xmlm core IStdlib ATDGenerated IBase IR Absint BO Costlib Concurrency Backend
(libraries xmlm core IStdlib ATDGenerated IBase IR Absint BO Checkers Costlib Concurrency Backend
TestDeterminators ClangFrontend ASTLanguage JavaFrontend)
(preprocess (pps ppx_compare))
)

Loading…
Cancel
Save