[issuelogs] less imperative

Reviewed By: jvillard

Differential Revision: D15278599

fbshipit-source-id: 54b190d94
master
Nikos Gorogiannis 6 years ago committed by Facebook Github Bot
parent 1d846ba631
commit 7106de35a3

@ -9,31 +9,35 @@
open! IStd open! IStd
let errLogMap = ref Typ.Procname.Map.empty type t = Errlog.t Typ.Procname.Map.t
let get_errlog procname = let empty = Typ.Procname.Map.empty
try Typ.Procname.Map.find procname !errLogMap
with Caml.Not_found -> let get_or_add ~proc m =
let errlog = Errlog.empty () in match Typ.Procname.Map.find_opt proc m with
errLogMap := Typ.Procname.Map.add procname errlog !errLogMap ; | Some errlog ->
errlog (m, errlog)
| None ->
let errlog = Errlog.empty () in
let m = Typ.Procname.Map.add proc errlog m in
(m, errlog)
let issues_serializer : Errlog.t Typ.Procname.Map.t Serialization.serializer = let issues_serializer : Errlog.t Typ.Procname.Map.t Serialization.serializer =
Serialization.create_serializer Serialization.Key.issues Serialization.create_serializer Serialization.Key.issues
let iter f = Typ.Procname.Map.iter f !errLogMap let iter ~f m = Typ.Procname.Map.iter f m
let store directory source_file = let store ~dir ~file m =
if not (Typ.Procname.Map.is_empty !errLogMap) then ( if not (Typ.Procname.Map.is_empty m) then (
let abbrev_source_file = DB.source_file_encoding source_file in let abbrev_source_file = DB.source_file_encoding file in
let issues_dir = Config.results_dir ^/ directory in let issues_dir = Config.results_dir ^/ dir in
Utils.create_dir issues_dir ; Utils.create_dir issues_dir ;
let filename = let filename =
DB.filename_from_string (Filename.concat issues_dir (abbrev_source_file ^ ".issue")) DB.filename_from_string (Filename.concat issues_dir (abbrev_source_file ^ ".issue"))
in in
Serialization.write_to_file issues_serializer filename ~data:!errLogMap ) Serialization.write_to_file issues_serializer filename ~data:m )
else () else ()
@ -42,27 +46,26 @@ let load_issues issues_file = Serialization.read_from_file issues_serializer iss
(** Load all the issues in the given dir and update the issues map *) (** Load all the issues in the given dir and update the issues map *)
let load dir = let load dir =
let () = errLogMap := Typ.Procname.Map.empty in
let issues_dir = Filename.concat Config.results_dir dir in let issues_dir = Filename.concat Config.results_dir dir in
let children_opt = try Some (Sys.readdir issues_dir) with Sys_error _ -> None in let load_issues_to_map init issues_file =
let load_issues_to_map issues_file =
let file = DB.filename_from_string (Filename.concat issues_dir issues_file) in let file = DB.filename_from_string (Filename.concat issues_dir issues_file) in
match load_issues file with load_issues file
| Some map -> |> Option.fold ~init ~f:(fun acc map ->
errLogMap := Typ.Procname.Map.merge
Typ.Procname.Map.merge (fun _ issues1 issues2 ->
(fun _ issues1 issues2 -> match (issues1, issues2) with
match (issues1, issues2) with | Some issues1, Some issues2 ->
| Some issues1, Some issues2 -> Errlog.update issues1 issues2 ; Some issues1
Errlog.update issues1 issues2 ; Some issues1 | Some issues1, None ->
| Some issues1, None -> Some issues1
Some issues1 | None, Some issues2 ->
| None, Some issues2 -> Some issues2
Some issues2 | None, None ->
| None, None -> None )
None ) acc map )
!errLogMap map
| None ->
()
in in
match children_opt with Some children -> Array.iter ~f:load_issues_to_map children | None -> () match Sys.readdir issues_dir with
| children ->
Array.fold children ~init:empty ~f:load_issues_to_map
| exception Sys_error _ ->
empty

@ -7,19 +7,21 @@
open! IStd open! IStd
(** Module to store a map from procnames to error logs. Starts with an empty map. *) (** Module for maps from procnames to error logs. *)
type t
val iter : (Typ.Procname.t -> Errlog.t -> unit) -> unit val empty : t
val iter : f:(Typ.Procname.t -> Errlog.t -> unit) -> t -> unit
(** iterate a function on map contents *) (** iterate a function on map contents *)
val get_errlog : Typ.Procname.t -> Errlog.t val get_or_add : proc:Typ.Procname.t -> t -> t * Errlog.t
(** Get the error log for a given procname. If not present, then add the association from (** Get the error log for a given procname. If there is none, add an empty one to the map.
procname to an empty error log and return the latter. *) Return the resulting map together with the errlog. *)
val store : string -> SourceFile.t -> unit val store : dir:string -> file:SourceFile.t -> t -> unit
(** If there are any issues in the log, [store dirname filename] stores map to [infer-out/dirname/filename]. (** If there are any issues in the log, [store ~dir ~file] stores map to [infer-out/dir/file].
Otherwise, no file is written. *) Otherwise, no file is written. *)
val load : string -> unit val load : string -> t
(** [load directory] resets the issue map first, then walks [infer-out/directory], merging all (** [load directory] walks [infer-out/directory], merging maps stored in files into one map. *)
maps stored in the found files into the current map. *)

@ -1223,8 +1223,8 @@ let pp_summary_and_issues formats_by_report_kind issue_formats =
List.iter List.iter
[Config.lint_issues_dir_name; Config.starvation_issues_dir_name; Config.racerd_issues_dir_name] [Config.lint_issues_dir_name; Config.starvation_issues_dir_name; Config.racerd_issues_dir_name]
~f:(fun dir_name -> ~f:(fun dir_name ->
IssueLog.load dir_name ; IssueLog.load dir_name
IssueLog.iter (pp_lint_issues filters formats_by_report_kind linereader) ) ; |> IssueLog.iter ~f:(pp_lint_issues filters formats_by_report_kind linereader) ) ;
finalize_and_close_files formats_by_report_kind stats finalize_and_close_files formats_by_report_kind stats

@ -82,12 +82,13 @@ let log_error = log_issue_from_summary_simplified Exceptions.Error
let log_warning = log_issue_from_summary_simplified Exceptions.Warning let log_warning = log_issue_from_summary_simplified Exceptions.Warning
let log_issue_external procname severity ~loc ~ltr ?access issue_type error_message = let log_issue_external procname ~issue_log severity ~loc ~ltr ?access issue_type error_message =
let exn = checker_exception issue_type error_message in let exn = checker_exception issue_type error_message in
let errlog = IssueLog.get_errlog procname in let issue_log, errlog = IssueLog.get_or_add issue_log ~proc:procname in
let node = Errlog.UnknownNode in let node = Errlog.UnknownNode in
log_issue_from_errlog procname ~clang_method_kind:None severity errlog ~loc ~node ~session:0 ~ltr log_issue_from_errlog procname ~clang_method_kind:None severity errlog ~loc ~node ~session:0 ~ltr
~access ~extras:None exn ~access ~extras:None exn ;
issue_log
let log_error_using_state summary exn = let log_error_using_state summary exn =

@ -45,13 +45,14 @@ val log_error_using_state : Summary.t -> exn -> unit
val log_issue_external : val log_issue_external :
Typ.Procname.t Typ.Procname.t
-> issue_log:IssueLog.t
-> Exceptions.severity -> Exceptions.severity
-> loc:Location.t -> loc:Location.t
-> ltr:Errlog.loc_trace -> ltr:Errlog.loc_trace
-> ?access:string -> ?access:string
-> IssueType.t -> IssueType.t
-> string -> string
-> unit -> IssueLog.t
(** Log an issue to the error log in [IssueLog] associated with the given procname. *) (** Log an issue to the error log in [IssueLog] associated with the given procname. *)
val is_suppressed : val is_suppressed :

@ -374,6 +374,7 @@ let linters_files =
let do_frontend_checks (trans_unit_ctx : CFrontend_config.translation_unit_context) ast = let do_frontend_checks (trans_unit_ctx : CFrontend_config.translation_unit_context) ast =
CFrontend_errors.issue_log := IssueLog.empty ;
L.(debug Capture Quiet) L.(debug Capture Quiet)
"Loading the following linters files: %a@\n" "Loading the following linters files: %a@\n"
(Pp.comma_seq Format.pp_print_string) (Pp.comma_seq Format.pp_print_string)
@ -400,7 +401,7 @@ let do_frontend_checks (trans_unit_ctx : CFrontend_config.translation_unit_conte
CFrontend_errors.invoke_set_of_checkers_on_node parsed_linters context CFrontend_errors.invoke_set_of_checkers_on_node parsed_linters context
(Ctl_parser_types.Decl ast) ; (Ctl_parser_types.Decl ast) ;
List.iter ~f:(do_frontend_checks_decl parsed_linters context active_map) allowed_decls ; List.iter ~f:(do_frontend_checks_decl parsed_linters context active_map) allowed_decls ;
IssueLog.store Config.lint_issues_dir_name source_file ; IssueLog.store !CFrontend_errors.issue_log ~dir:Config.lint_issues_dir_name ~file:source_file ;
L.(debug Linters Medium) "End linting file %a@\n" SourceFile.pp source_file ; L.(debug Linters Medium) "End linting file %a@\n" SourceFile.pp source_file ;
CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file
(*if CFrontend_config.tableaux_evaluation then ( (*if CFrontend_config.tableaux_evaluation then (

@ -459,6 +459,8 @@ let expand_checkers macro_map path_map checkers =
List.map ~f:expand_one_checker checkers List.map ~f:expand_one_checker checkers
let issue_log = ref IssueLog.empty
(** Add a frontend warning with a description desc at location loc to the errlog of a proc desc *) (** Add a frontend warning with a description desc at location loc to the errlog of a proc desc *)
let log_frontend_issue method_decl_opt (node : Ctl_parser_types.ast_node) let log_frontend_issue method_decl_opt (node : Ctl_parser_types.ast_node)
(issue_desc : CIssue.issue_desc) = (issue_desc : CIssue.issue_desc) =
@ -469,7 +471,8 @@ let log_frontend_issue method_decl_opt (node : Ctl_parser_types.ast_node)
| None -> | None ->
Typ.Procname.Linters_dummy_method Typ.Procname.Linters_dummy_method
in in
let errlog = IssueLog.get_errlog procname in let issue_log', errlog = IssueLog.get_or_add ~proc:procname !issue_log in
issue_log := issue_log' ;
let err_desc = let err_desc =
Errdesc.explain_frontend_warning issue_desc.description issue_desc.suggestion issue_desc.loc Errdesc.explain_frontend_warning issue_desc.description issue_desc.suggestion issue_desc.loc
in in

@ -7,6 +7,8 @@
open! IStd open! IStd
val issue_log : IssueLog.t ref
type linter = type linter =
{ condition: CTL.t { condition: CTL.t
; issue_desc: CIssue.issue_desc ; issue_desc: CIssue.issue_desc

@ -722,9 +722,9 @@ let make_trace ~report_kind original_path =
(original_trace, original_end, None) (original_trace, original_end, None)
let log_issue current_pname ~loc ~ltr ~access issue_type error_message = let log_issue current_pname ~issue_log ~loc ~ltr ~access issue_type error_message =
Reporting.log_issue_external current_pname Exceptions.Warning ~loc ~ltr ~access issue_type Reporting.log_issue_external current_pname Exceptions.Warning ~issue_log ~loc ~ltr ~access
error_message issue_type error_message
type reported_access = type reported_access =
@ -733,7 +733,7 @@ type reported_access =
; tenv: Tenv.t ; tenv: Tenv.t
; procdesc: Procdesc.t } ; procdesc: Procdesc.t }
let report_thread_safety_violation ~make_description ~report_kind let report_thread_safety_violation ~issue_log ~make_description ~report_kind
({threads; snapshot; tenv; procdesc} : reported_access) = ({threads; snapshot; tenv; procdesc} : reported_access) =
let open RacerDDomain in let open RacerDDomain in
let pname = Procdesc.get_proc_name procdesc in let pname = Procdesc.get_proc_name procdesc in
@ -750,10 +750,10 @@ let report_thread_safety_violation ~make_description ~report_kind
let error_message = F.sprintf "%s%s" description explanation in let error_message = F.sprintf "%s%s" description explanation in
let end_locs = Option.to_list original_end @ Option.to_list conflict_end in let end_locs = Option.to_list original_end @ Option.to_list conflict_end in
let access = IssueAuxData.encode end_locs in let access = IssueAuxData.encode end_locs in
log_issue pname ~loc ~ltr ~access issue_type error_message log_issue pname ~issue_log ~loc ~ltr ~access issue_type error_message
let report_unannotated_interface_violation reported_pname (reported_access : reported_access) = let report_unannotated_interface_violation ~issue_log reported_pname reported_access =
match reported_pname with match reported_pname with
| Typ.Procname.Java java_pname -> | Typ.Procname.Java java_pname ->
let class_name = Typ.Procname.Java.get_class_name java_pname in let class_name = Typ.Procname.Java.get_class_name java_pname in
@ -764,11 +764,11 @@ let report_unannotated_interface_violation reported_pname (reported_access : rep
(MF.wrap_monospaced Typ.Procname.pp) (MF.wrap_monospaced Typ.Procname.pp)
reported_pname MF.pp_monospaced class_name MF.pp_monospaced "@ThreadSafe" reported_pname MF.pp_monospaced class_name MF.pp_monospaced "@ThreadSafe"
in in
report_thread_safety_violation ~make_description ~report_kind:UnannotatedInterface report_thread_safety_violation ~issue_log ~make_description ~report_kind:UnannotatedInterface
reported_access reported_access
| _ -> | _ ->
(* skip reporting on C++ *) (* skip reporting on C++ *)
() issue_log
let make_unprotected_write_description pname final_sink_site initial_sink_site final_sink = let make_unprotected_write_description pname final_sink_site initial_sink_site final_sink =
@ -994,7 +994,7 @@ let should_report_guardedby_violation classname_str ({snapshot; tenv; procdesc}
currently not distinguishing different locks, and are treating "known to be confined to a currently not distinguishing different locks, and are treating "known to be confined to a
thread" as if "known to be confined to UI thread". thread" as if "known to be confined to UI thread".
*) *)
let report_unsafe_accesses classname (aggregated_access_map : ReportMap.t) = let report_unsafe_accesses ~issue_log classname (aggregated_access_map : ReportMap.t) =
let open RacerDDomain in let open RacerDDomain in
let open RacerDModels in let open RacerDModels in
let is_duplicate_report ({snapshot; procdesc} : reported_access) let is_duplicate_report ({snapshot; procdesc} : reported_access)
@ -1032,10 +1032,10 @@ let report_unsafe_accesses classname (aggregated_access_map : ReportMap.t) =
{reported with reported_unannotated_calls; reported_sites} {reported with reported_unannotated_calls; reported_sites}
else reported else reported
in in
let report_unsafe_access accesses reported_acc let report_unsafe_access accesses (reported_acc, issue_log)
({snapshot; threads; tenv; procdesc} as reported_access) = ({snapshot; threads; tenv; procdesc} as reported_access) =
let pname = Procdesc.get_proc_name procdesc in let pname = Procdesc.get_proc_name procdesc in
if is_duplicate_report reported_access reported_acc then reported_acc if is_duplicate_report reported_access reported_acc then (reported_acc, issue_log)
else else
match snapshot.access.elem with match snapshot.access.elem with
| Access.InterfaceCall reported_pname | Access.InterfaceCall reported_pname
@ -1043,10 +1043,12 @@ let report_unsafe_accesses classname (aggregated_access_map : ReportMap.t) =
&& ThreadsDomain.is_any threads && ThreadsDomain.is_any threads
&& is_marked_thread_safe procdesc tenv -> && is_marked_thread_safe procdesc tenv ->
(* un-annotated interface call + no lock in method marked thread-safe. warn *) (* un-annotated interface call + no lock in method marked thread-safe. warn *)
report_unannotated_interface_violation reported_pname reported_access ; let issue_log =
update_reported reported_access reported_acc report_unannotated_interface_violation ~issue_log reported_pname reported_access
in
(update_reported reported_access reported_acc, issue_log)
| Access.InterfaceCall _ -> | Access.InterfaceCall _ ->
reported_acc (reported_acc, issue_log)
| (Access.Write _ | ContainerWrite _) when Typ.Procname.is_java pname -> | (Access.Write _ | ContainerWrite _) when Typ.Procname.is_java pname ->
let conflict = let conflict =
if ThreadsDomain.is_any threads then if ThreadsDomain.is_any threads then
@ -1064,14 +1066,17 @@ let report_unsafe_accesses classname (aggregated_access_map : ReportMap.t) =
if if
AccessSnapshot.is_unprotected snapshot AccessSnapshot.is_unprotected snapshot
&& (Option.is_some conflict || ThreadsDomain.is_any threads) && (Option.is_some conflict || ThreadsDomain.is_any threads)
then ( then
report_thread_safety_violation ~make_description:make_unprotected_write_description let issue_log =
~report_kind:(WriteWriteRace conflict) reported_access ; report_thread_safety_violation ~issue_log
update_reported reported_access reported_acc ) ~make_description:make_unprotected_write_description
else reported_acc ~report_kind:(WriteWriteRace conflict) reported_access
in
(update_reported reported_access reported_acc, issue_log)
else (reported_acc, issue_log)
| Access.Write _ | ContainerWrite _ -> | Access.Write _ | ContainerWrite _ ->
(* Do not report unprotected writes for ObjC_Cpp *) (* Do not report unprotected writes for ObjC_Cpp *)
reported_acc (reported_acc, issue_log)
| (Access.Read _ | ContainerRead _) when AccessSnapshot.is_unprotected snapshot -> | (Access.Read _ | ContainerRead _) when AccessSnapshot.is_unprotected snapshot ->
(* unprotected read. report all writes as conflicts for java. for c++ filter out (* unprotected read. report all writes as conflicts for java. for c++ filter out
unprotected writes *) unprotected writes *)
@ -1083,13 +1088,16 @@ let report_unsafe_accesses classname (aggregated_access_map : ReportMap.t) =
else not (AccessSnapshot.is_unprotected snapshot) else not (AccessSnapshot.is_unprotected snapshot)
in in
List.find ~f:is_conflict accesses List.find ~f:is_conflict accesses
|> Option.value_map ~default:reported_acc ~f:(fun conflict -> |> Option.value_map ~default:(reported_acc, issue_log) ~f:(fun conflict ->
let make_description = let make_description =
make_read_write_race_description ~read_is_sync:false conflict make_read_write_race_description ~read_is_sync:false conflict
in in
let report_kind = ReadWriteRace conflict.snapshot.access in let report_kind = ReadWriteRace conflict.snapshot.access in
report_thread_safety_violation ~make_description ~report_kind reported_access ; let issue_log =
update_reported reported_access reported_acc ) report_thread_safety_violation ~issue_log ~make_description ~report_kind
reported_access
in
(update_reported reported_access reported_acc, issue_log) )
| Access.Read _ | ContainerRead _ -> | Access.Read _ | ContainerRead _ ->
(* protected read. report unprotected writes and opposite protected writes as conflicts *) (* protected read. report unprotected writes and opposite protected writes as conflicts *)
let can_conflict (snapshot1 : AccessSnapshot.t) (snapshot2 : AccessSnapshot.t) = let can_conflict (snapshot1 : AccessSnapshot.t) (snapshot2 : AccessSnapshot.t) =
@ -1102,45 +1110,49 @@ let report_unsafe_accesses classname (aggregated_access_map : ReportMap.t) =
else TraceElem.is_write other_snapshot.access && can_conflict snapshot other_snapshot else TraceElem.is_write other_snapshot.access && can_conflict snapshot other_snapshot
in in
List.find accesses ~f:is_conflict List.find accesses ~f:is_conflict
|> Option.value_map ~default:reported_acc ~f:(fun conflict -> |> Option.value_map ~default:(reported_acc, issue_log) ~f:(fun conflict ->
(* protected read with conflicting unprotected write(s). warn. *) (* protected read with conflicting unprotected write(s). warn. *)
let make_description = let make_description =
make_read_write_race_description ~read_is_sync:true conflict make_read_write_race_description ~read_is_sync:true conflict
in in
let report_kind = ReadWriteRace conflict.snapshot.access in let report_kind = ReadWriteRace conflict.snapshot.access in
report_thread_safety_violation ~make_description ~report_kind reported_access ; let issue_log =
update_reported reported_access reported_acc ) report_thread_safety_violation ~issue_log ~make_description ~report_kind
reported_access
in
(update_reported reported_access reported_acc, issue_log) )
in in
let report_accesses_on_location (reportable_accesses : reported_access list) init = let report_accesses_on_location reportable_accesses init =
(* Don't report on location if all accesses are on non-concurrent contexts *) (* Don't report on location if all accesses are on non-concurrent contexts *)
if if
List.for_all reportable_accesses ~f:(fun ({threads} : reported_access) -> List.for_all reportable_accesses ~f:(fun ({threads} : reported_access) ->
(* FIXME this should be any thread or no thread *)
ThreadsDomain.is_any threads |> not ) ThreadsDomain.is_any threads |> not )
then init then init
else List.fold reportable_accesses ~init ~f:(report_unsafe_access reportable_accesses) else List.fold reportable_accesses ~init ~f:(report_unsafe_access reportable_accesses)
in in
let report_guardedby_violations_on_location grouped_accesses init = let report_guardedby_violations_on_location grouped_accesses init =
if Config.racerd_guardedby then if Config.racerd_guardedby then
List.fold grouped_accesses ~init ~f:(fun acc r -> List.fold grouped_accesses ~init ~f:(fun (acc, issue_log) r ->
if should_report_guardedby_violation classname r && not (is_duplicate_report r acc) then ( if should_report_guardedby_violation classname r && not (is_duplicate_report r acc) then
report_thread_safety_violation ~make_description:make_guardedby_violation_description let issue_log =
~report_kind:GuardedByViolation r ; report_thread_safety_violation ~issue_log ~report_kind:GuardedByViolation
update_reported r acc ) ~make_description:make_guardedby_violation_description r
else acc ) in
(update_reported r acc, issue_log)
else (acc, issue_log) )
else init else init
in in
let report grouped_accesses reported_acc = let report grouped_accesses (reported, issue_log) =
(* reset the reported reads and writes for each memory location *) (* reset the reported reads and writes for each memory location *)
let reported_acc = let reported =
{ reported_acc with { reported with
reported_writes= Typ.Procname.Set.empty reported_writes= Typ.Procname.Set.empty
; reported_reads= Typ.Procname.Set.empty } ; reported_reads= Typ.Procname.Set.empty }
in in
report_guardedby_violations_on_location grouped_accesses reported_acc report_guardedby_violations_on_location grouped_accesses (reported, issue_log)
|> report_accesses_on_location grouped_accesses |> report_accesses_on_location grouped_accesses
in in
ReportMap.fold report aggregated_access_map empty_reported |> ignore ReportMap.fold report aggregated_access_map (empty_reported, issue_log) |> snd
(* create a map from [abstraction of a memory loc] -> accesses that (* create a map from [abstraction of a memory loc] -> accesses that
@ -1173,8 +1185,9 @@ let aggregate_by_class file_env =
(* Gathers results by analyzing all the methods in a file, then (* Gathers results by analyzing all the methods in a file, then
post-processes the results to check an (approximation of) thread post-processes the results to check an (approximation of) thread
safety *) safety *)
let file_analysis {Callbacks.procedures; source_file} = let file_analysis ({procedures; source_file} : Callbacks.cluster_callback_args) =
let init = IssueLog.empty in
aggregate_by_class procedures aggregate_by_class procedures
|> String.Map.iteri ~f:(fun ~key:classname ~data:class_env -> |> String.Map.fold ~init ~f:(fun ~key:classname ~data:class_env issue_log ->
report_unsafe_accesses classname (make_results_table class_env) ) ; make_results_table class_env |> report_unsafe_accesses ~issue_log classname )
IssueLog.store Config.racerd_issues_dir_name source_file |> IssueLog.store ~dir:Config.racerd_issues_dir_name ~file:source_file

@ -191,7 +191,7 @@ module ReportMap : sig
val add_strict_mode_volation : report_add_t val add_strict_mode_volation : report_add_t
val log : Tenv.t -> Procdesc.t -> t -> unit val log : IssueLog.t -> Tenv.t -> Procdesc.t -> t -> IssueLog.t
end = struct end = struct
type problem = type problem =
| Starvation of StarvationDomain.Event.severity_t | Starvation of StarvationDomain.Event.severity_t
@ -229,8 +229,8 @@ end = struct
add loc report map add loc report map
let log tenv pdesc map = let log start_issue_log tenv pdesc map =
let log_report loc {problem; pname; ltr; message} = let log_report ~issue_log loc {problem; pname; ltr; message} =
let issue_type = let issue_type =
match problem with match problem with
| Deadlock _ -> | Deadlock _ ->
@ -240,22 +240,25 @@ end = struct
| StrictModeViolation _ -> | StrictModeViolation _ ->
IssueType.strict_mode_violation IssueType.strict_mode_violation
in in
if Reporting.is_suppressed tenv pdesc issue_type then () if Reporting.is_suppressed tenv pdesc issue_type then issue_log
else Reporting.log_issue_external pname Exceptions.Error ~loc ~ltr issue_type message else
Reporting.log_issue_external ~issue_log pname Exceptions.Error ~loc ~ltr issue_type message
in in
let mk_deduped_report ({message} as report) = let mk_deduped_report ({message} as report) =
{ report with { report with
message= Printf.sprintf "%s Additional report(s) on the same line were suppressed." message message= Printf.sprintf "%s Additional report(s) on the same line were suppressed." message
} }
in in
let log_reports compare loc = function let log_reports compare loc reports issue_log =
match reports with
| [] -> | [] ->
() issue_log
| [(_, report)] -> | [(_, report)] ->
log_report loc report log_report ~issue_log loc report
| reports -> | reports ->
List.max_elt ~compare reports List.max_elt ~compare reports
|> Option.iter ~f:(fun (_, rep) -> mk_deduped_report rep |> log_report loc) |> Option.fold ~init:issue_log ~f:(fun acc (_, rep) ->
mk_deduped_report rep |> log_report ~issue_log:acc loc )
in in
let filter_map_deadlock = function {problem= Deadlock l} as r -> Some (l, r) | _ -> None in let filter_map_deadlock = function {problem= Deadlock l} as r -> Some (l, r) | _ -> None in
let filter_map_starvation = function let filter_map_starvation = function
@ -273,15 +276,15 @@ end = struct
let compare_reports weight_compare (w, r) (w', r') = let compare_reports weight_compare (w, r) (w', r') =
match weight_compare w w' with 0 -> String.compare r.message r'.message | result -> result match weight_compare w w' with 0 -> String.compare r.message r'.message | result -> result
in in
let log_location loc problems = let log_location loc problems issue_log =
let deadlocks = List.filter_map problems ~f:filter_map_deadlock in let deadlocks = List.filter_map problems ~f:filter_map_deadlock in
log_reports (compare_reports Int.compare) loc deadlocks ;
let starvations = List.filter_map problems ~f:filter_map_starvation in let starvations = List.filter_map problems ~f:filter_map_starvation in
log_reports (compare_reports StarvationDomain.Event.compare_severity_t) loc starvations ;
let strict_mode_violations = List.filter_map problems ~f:filter_map_strict_mode_violation in let strict_mode_violations = List.filter_map problems ~f:filter_map_strict_mode_violation in
log_reports (compare_reports Int.compare) loc strict_mode_violations log_reports (compare_reports Int.compare) loc deadlocks issue_log
|> log_reports (compare_reports StarvationDomain.Event.compare_severity_t) loc starvations
|> log_reports (compare_reports Int.compare) loc strict_mode_violations
in in
LocMap.iter log_location map LocMap.fold log_location map start_issue_log
end end
let should_report_deadlock_on_current_proc current_elem endpoint_elem = let should_report_deadlock_on_current_proc current_elem endpoint_elem =
@ -486,12 +489,14 @@ let report_starvation env {StarvationDomain.events; ui} report_map' =
let reporting {Callbacks.procedures; source_file} = let reporting {Callbacks.procedures; source_file} =
let report_procedure ((tenv, proc_desc) as env) = let report_procedure issue_log ((tenv, proc_desc) as env) =
if should_report proc_desc then if should_report proc_desc then
Payload.read proc_desc (Procdesc.get_proc_name proc_desc) Payload.read proc_desc (Procdesc.get_proc_name proc_desc)
|> Option.iter ~f:(fun summary -> |> Option.value_map ~default:issue_log ~f:(fun summary ->
report_deadlocks env summary ReportMap.empty report_deadlocks env summary ReportMap.empty
|> report_starvation env summary |> ReportMap.log tenv proc_desc ) |> report_starvation env summary
|> ReportMap.log issue_log tenv proc_desc )
else issue_log
in in
List.iter procedures ~f:report_procedure ; List.fold procedures ~init:IssueLog.empty ~f:report_procedure
IssueLog.store Config.starvation_issues_dir_name source_file |> IssueLog.store ~dir:Config.starvation_issues_dir_name ~file:source_file

@ -54,61 +54,41 @@ codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.Guarded
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$4.readFromInnerClassBad2():java.lang.String, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFromInnerClassBad2()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$4.readFromInnerClassBad2():java.lang.String, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFromInnerClassBad2()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$Sub.badSub():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure badSub()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$Sub.badSub():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure badSub()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$Sub.badSub():void, 491, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.xForSub`,<Write on background thread>,access to `this.xForSub`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$Sub.badSub():void, 491, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.xForSub`,<Write on background thread>,access to `this.xForSub`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample$Sub.badSub():void, 491, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.xForSub`,<Write on background thread>,access to `this.xForSub`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByNormalLock():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure badGuardedByNormalLock()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByNormalLock():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure badGuardedByNormalLock()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByNormalLock():void, 526, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedbynl`,<Write on background thread>,access to `this.guardedbynl`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByNormalLock():void, 526, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedbynl`,<Write on background thread>,access to `this.guardedbynl`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByNormalLock():void, 526, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedbynl`,<Write on background thread>,access to `this.guardedbynl`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByReentrantLock():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure badGuardedByReentrantLock()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByReentrantLock():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure badGuardedByReentrantLock()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByReentrantLock():void, 530, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedbyrel`,<Write on background thread>,access to `this.guardedbyrel`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByReentrantLock():void, 530, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedbyrel`,<Write on background thread>,access to `this.guardedbyrel`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.badGuardedByReentrantLock():void, 530, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedbyrel`,<Write on background thread>,access to `this.guardedbyrel`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.byRefTrickyBad():java.lang.Object, 5, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure byRefTrickyBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.byRefTrickyBad():java.lang.Object, 5, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure byRefTrickyBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.byRefTrickyBad():java.lang.Object, 281, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.g`,<Write trace>,access to `this.g`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.byRefTrickyBad():java.lang.Object, 281, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.g`,<Write trace>,access to `this.g`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.byRefTrickyBad():java.lang.Object, 281, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.g`,<Write trace>,access to `this.g`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure guardedByTypeSyntaxBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure guardedByTypeSyntaxBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure guardedByTypeSyntaxBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure guardedByTypeSyntaxBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 573, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedByLock1`,<Write on background thread>,access to `this.guardedByLock1`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 573, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedByLock1`,<Write on background thread>,access to `this.guardedByLock1`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 573, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedByLock1`,<Write on background thread>,access to `this.guardedByLock1`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 574, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedByLock2`,<Write on background thread>,access to `this.guardedByLock2`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 574, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedByLock2`,<Write on background thread>,access to `this.guardedByLock2`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.guardedByTypeSyntaxBad():void, 574, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.guardedByLock2`,<Write on background thread>,access to `this.guardedByLock2`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFAfterBlockBad():void, 3, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFAfterBlockBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFAfterBlockBad():void, 3, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFAfterBlockBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFAfterBlockBad():void, 98, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFAfterBlockBad():void, 98, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFAfterBlockBad():void, 98, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBad():void, 66, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBad():void, 66, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBad():void, 66, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadButSuppressed():void, 71, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadButSuppressed():void, 71, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadButSuppressed():void, 71, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadButSuppressedOther():void, 76, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadButSuppressedOther():void, 76, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadButSuppressedOther():void, 76, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongAnnotation():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFBadWrongAnnotation()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongAnnotation():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFBadWrongAnnotation()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongAnnotation():void, 109, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongAnnotation():void, 109, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongAnnotation():void, 109, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongLock():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFBadWrongLock()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongLock():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readFBadWrongLock()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongLock():void, 85, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongLock():void, 85, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFBadWrongLock():void, 85, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFOkMethodAnnotated():void, 114, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFOkMethodAnnotated():void, 114, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFOkMethodAnnotated():void, 114, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFOkSynchronized():void, 127, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFOkSynchronized():void, 127, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readFOkSynchronized():void, 127, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readGFromCopyOk():void, 267, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.mCopyOfG`,<Write trace>,access to `this.mCopyOfG`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readGFromCopyOk():void, 267, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.mCopyOfG`,<Write trace>,access to `this.mCopyOfG`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readGFromCopyOk():void, 267, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.mCopyOfG`,<Write trace>,access to `this.mCopyOfG`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readHBad():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readHBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readHBad():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readHBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readHBadSynchronizedMethodShouldntHelp():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readHBadSynchronizedMethodShouldntHelp()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.readHBadSynchronizedMethodShouldntHelp():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure readHBadSynchronizedMethodShouldntHelp()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.reassignCopyOk():void, 149, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `this.mCopyOfG`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.reassignCopyOk():void, 149, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `this.mCopyOfG`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.reassignCopyOk():void, 149, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `this.mCopyOfG`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodReadBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure synchronizedMethodReadBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodReadBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure synchronizedMethodReadBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodReadBad():void, 138, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodReadBad():void, 138, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodReadBad():void, 138, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this.f`,<Write trace>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodWriteBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure synchronizedMethodWriteBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedMethodWriteBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure synchronizedMethodWriteBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedOnThisBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure synchronizedOnThisBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedOnThisBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure synchronizedOnThisBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedOnThisBad():void, 205, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `infer.GuardedByExample.sGuardedByClass`,<Write trace>,access to `infer.GuardedByExample.sGuardedByClass`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedOnThisBad():void, 205, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `infer.GuardedByExample.sGuardedByClass`,<Write trace>,access to `infer.GuardedByExample.sGuardedByClass`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.synchronizedOnThisBad():void, 205, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `infer.GuardedByExample.sGuardedByClass`,<Write trace>,access to `infer.GuardedByExample.sGuardedByClass`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFAfterBlockBad():void, 3, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure writeFAfterBlockBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFAfterBlockBad():void, 3, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure writeFAfterBlockBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFAfterBlockBad():void, 104, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFAfterBlockBad():void, 104, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFAfterBlockBad():void, 104, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure writeFBad()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBad():void, 1, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure writeFBad()]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBad():void, 80, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.f`,<Write on background thread>,access to `this.f`] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBad():void, 80, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.f`,<Write on background thread>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBad():void, 80, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Write on unknown thread>,access to `this.f`,<Write on background thread>,access to `this.f`]
codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBadWrongLock():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure writeFBadWrongLock()] codetoanalyze/java/infer/GuardedByExample.java, codetoanalyze.java.infer.GuardedByExample.writeFBadWrongLock():void, 2, UNSAFE_GUARDED_BY_ACCESS, no_bucket, ERROR, [start of procedure writeFBadWrongLock()]
codetoanalyze/java/infer/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getAfterClearBad():void, 5, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure getAfterClearBad()] codetoanalyze/java/infer/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getAfterClearBad():void, 5, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure getAfterClearBad()]
codetoanalyze/java/infer/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getAfterRemovingTheKeyBad():void, 5, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure getAfterRemovingTheKeyBad()] codetoanalyze/java/infer/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getAfterRemovingTheKeyBad():void, 5, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure getAfterRemovingTheKeyBad()]

Loading…
Cancel
Save