print location of errors in infer source code in debug mode

Summary:
public
- add to json reports the location in the ocaml code of assertions raised
  during the analysis
- only add when in debug mode. For this, add a flag to `InferPrint` that is
  passed by the toplevel `infer` whenever `infer -g` is used.

Reviewed By: jeremydubreil

Differential Revision: D2891286

fb-gh-sync-id: ad4577c
master
Jules Villard 9 years ago committed by facebook-github-bot-7
parent 8545a0310e
commit e11395d199

@ -522,6 +522,8 @@ class Infer:
if self.javac.annotations_out is not None:
infer_print_options += [
'-local_config', self.javac.annotations_out]
if self.args.debug:
infer_print_options.append('-with_infer_src_loc')
exit_status = subprocess.check_call(
infer_print_cmd + infer_print_options
)

@ -93,6 +93,10 @@ JSON_INDEX_TRACE_DESCRIPTION = 'description'
JSON_INDEX_TRACE_NODE_TAGS = 'node_tags'
JSON_INDEX_TRACE_NODE_TAGS_TAG = 'tags'
JSON_INDEX_TRACE_NODE_TAGS_VALUE = 'value'
JSON_INDEX_INFER_SOURCE_LOC = 'infer_source_loc'
JSON_INDEX_ISL_FILE = 'file'
JSON_INDEX_ISL_LINE = 'line'
JSON_INDEX_ISL_COLUMN = 'column'
QUALIFIER_TAGS = 'qualifier_tags'
BUCKET_TAGS = 'bucket'
@ -146,11 +150,20 @@ def text_of_report(report):
line = report[JSON_INDEX_LINE]
error_type = report[JSON_INDEX_TYPE]
msg = report[JSON_INDEX_QUALIFIER]
return u'%s:%d: %s: %s\n %s' % (
infer_loc = ''
if JSON_INDEX_INFER_SOURCE_LOC in report:
loc = report[JSON_INDEX_INFER_SOURCE_LOC]
infer_loc = u' (%s:%d:%d)' % (
loc[JSON_INDEX_ISL_FILE],
loc[JSON_INDEX_ISL_LINE],
loc[JSON_INDEX_ISL_COLUMN],
)
return u'%s:%d: %s: %s%s\n %s' % (
filename,
line,
kind.lower(),
error_type,
infer_loc,
msg,
)

@ -64,8 +64,16 @@ let empty () = ErrLogHash.create 13
(** type of the function to be passed to iter *)
type iter_fun =
(int * int) -> Location.t -> Exceptions.err_kind -> bool -> Localise.t -> Localise.error_desc ->
string -> loc_trace -> Prop.normal Prop.t option -> Exceptions.err_class -> unit
(int * int) ->
Location.t ->
ml_location option ->
Exceptions.err_kind ->
bool ->
Localise.t -> Localise.error_desc -> string ->
loc_trace ->
Prop.normal Prop.t option ->
Exceptions.err_class ->
unit
(** Apply f to nodes and error names *)
let iter (f: iter_fun) (err_log: t) =
@ -73,7 +81,7 @@ let iter (f: iter_fun) (err_log: t) =
ErrDataSet.iter
(fun (node_id_key, section, loc, mloco, ltr, pre_opt, eclass) ->
f
node_id_key loc ekind in_footprint err_name
node_id_key loc mloco ekind in_footprint err_name
desc severity ltr pre_opt eclass)
set)
err_log

@ -9,6 +9,8 @@
(** Module for error logs. *)
open Utils
(** Element of a loc trace *)
type loc_trace_elem = {
lt_level : int; (** nesting level of procedure calls *)
@ -28,8 +30,16 @@ val empty : unit -> t
(** type of the function to be passed to iter *)
type iter_fun =
(int * int) -> Location.t -> Exceptions.err_kind -> bool -> Localise.t -> Localise.error_desc ->
string -> loc_trace -> Prop.normal Prop.t option -> Exceptions.err_class -> unit
(int * int) ->
Location.t ->
ml_location option ->
Exceptions.err_kind ->
bool ->
Localise.t -> Localise.error_desc -> string ->
loc_trace ->
Prop.normal Prop.t option ->
Exceptions.err_class ->
unit
(** Apply f to nodes and error names *)
val iter : iter_fun -> t -> unit

@ -64,6 +64,9 @@ let precondition_stats = ref false
(** name of the file to load analysis results from *)
let load_analysis_results = ref None
(** If true then include Infer source code locations in json reports *)
let reports_include_ml_loc = ref false
(** name of the file to load save results to *)
let save_analysis_results = ref None
@ -114,6 +117,8 @@ let arg_desc =
"Path to the .inferconfig file";
"-local_config", Arg.String (fun s -> Inferconfig.local_config := Some s), Some "Path",
"Path to local config file";
"-with_infer_src_loc", Arg.Set reports_include_ml_loc, None,
"include the location (in the Infer source code) from where reports are generated";
] in
Arg.create_options_desc false "Options" desc in
let reserved_arg =
@ -414,7 +419,7 @@ module BugsCsv = struct
let pp_bugs error_filter fname fmt summary =
let pp x = F.fprintf fmt x in
let err_log = summary.Specs.attributes.ProcAttributes.err_log in
let pp_row (node_id, node_key) loc ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
let pp_row (node_id, node_key) loc ml_loc_opt ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
if in_footprint && error_filter error_desc error_name then
let err_desc_string = error_desc_to_csv_string error_desc in
let err_advice_string = error_advice_to_csv_string error_desc in
@ -463,13 +468,17 @@ module BugsJson = struct
let pp_bugs error_filter fname fmt summary =
let pp x = F.fprintf fmt x in
let err_log = summary.Specs.attributes.ProcAttributes.err_log in
let pp_row (node_id, node_key) loc ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
let pp_row (node_id, node_key) loc ml_loc_opt ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
if in_footprint && error_filter error_desc error_name then
let kind = Exceptions.err_kind_string ekind in
let bug_type = Localise.to_string error_name in
let procedure_id = Procname.to_filename (Specs.get_proc_name summary) in
let file =
DB.source_file_to_string summary.Specs.attributes.ProcAttributes.loc.Location.file in
let json_mloc = match ml_loc_opt with
| Some (file, line, column) when !reports_include_ml_loc ->
Some Jsonbug_j.{ file; line; column }
| _ -> None in
let bug = {
bug_class = Exceptions.err_class_string eclass;
kind = kind;
@ -485,6 +494,7 @@ module BugsJson = struct
qualifier_tags = error_desc_to_qualifier_tags_records error_desc;
hash = get_bug_hash kind bug_type procedure_id file node_key error_desc;
dotty = error_desc_to_dotty_string error_desc;
infer_source_loc = json_mloc;
} in
if not !is_first_item then pp "," else is_first_item := false;
pp "%s@?" (string_of_jsonbug bug) in
@ -495,7 +505,7 @@ module BugsTxt = struct
(** Write bug report in text format *)
let pp_bugs error_filter fname fmt summary =
let err_log = summary.Specs.attributes.ProcAttributes.err_log in
let pp_row (node_id, node_key) loc ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
let pp_row (node_id, node_key) loc ml_loc_opt ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
if in_footprint && error_filter error_desc error_name then
Exceptions.pp_err (node_id, node_key) loc ekind error_name error_desc None fmt () in
Errlog.iter pp_row err_log
@ -535,7 +545,7 @@ module BugsXml = struct
(** print bugs from summary in xml *)
let pp_bugs error_filter linereader fmt summary =
let err_log = summary.Specs.attributes.ProcAttributes.err_log in
let do_row (node_id, node_key) loc ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
let do_row (node_id, node_key) loc ml_loc_opt ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
if in_footprint && error_filter error_desc error_name then
let err_desc_string = error_desc_to_xml_string error_desc in
let precondition_tree () = match pre_opt with
@ -729,7 +739,7 @@ module Stats = struct
let process_err_log error_filter linereader err_log stats =
let found_errors = ref false in
let process_row (node_id, node_key) loc ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
let process_row (node_id, node_key) loc ml_loc_opt ekind in_footprint error_name error_desc severity ltr pre_opt eclass =
let type_str = Localise.to_string error_name in
if in_footprint && error_filter error_desc error_name
then match ekind with

@ -1,33 +1,40 @@
type tag_value_record = {
tag : string;
value : string;
tag : string;
value : string;
}
type json_trace_item = {
level : int;
filename : string;
line_number : int;
description : string;
node_tags : tag_value_record list;
level : int;
filename : string;
line_number : int;
description : string;
node_tags : tag_value_record list;
}
type loc = {
file: string;
line: int;
column: int;
}
type jsonbug = {
bug_class : string;
kind : string;
bug_type : string;
qualifier : string;
severity : string;
line: int;
procedure : string;
procedure_id : string;
file : string;
bug_trace : json_trace_item list;
key : int;
qualifier_tags : tag_value_record list;
hash : int;
dotty : string;
bug_class : string;
kind : string;
bug_type : string;
qualifier : string;
severity : string;
line: int;
procedure : string;
procedure_id : string;
file : string;
bug_trace : json_trace_item list;
key : int;
qualifier_tags : tag_value_record list;
hash : int;
dotty : string;
?infer_source_loc: loc option;
}
type json_trace = {
trace : json_trace_item list;
trace : json_trace_item list;
}

@ -290,9 +290,8 @@ let proc_write_log whole_seconds cfg pname =
(** Creare a hash table mapping line numbers to the set of errors occurring on that line *)
let create_errors_per_line err_log =
let err_per_line = Hashtbl.create 17 in
let add_err node_id_key loc ekind in_footprint err_name desc severity ltr pre_opt eclass =
let add_err node_id_key loc ml_loc_opt ekind in_footprint err_name desc severity ltr pre_opt eclass =
let err_str = Localise.to_string err_name ^ " " ^ (pp_to_string Localise.pp_error_desc desc) in
(* if in_footprint then *)
try
let set = Hashtbl.find err_per_line loc.Location.line in
Hashtbl.replace err_per_line loc.Location.line (StringSet.add err_str set)

Loading…
Cancel
Save