[checkers] enable biabduction by default + docs and logs improvements

Summary:
Refactor `RegisterCheckers` to give a record type to checkers instead of a tuple type.

Print active checkers with their per-language information.

Improve the manual entries slightly.

Reviewed By: sblackshear

Differential Revision: D6051167

fbshipit-source-id: 90bcb61
master
Jules Villard 7 years ago committed by Facebook Github Bot
parent 1bc62212ba
commit 588142c908

@ -252,10 +252,7 @@ let do_filter (diff: Differential.t) (renamings: FileRenamings.t) ~(skip_duplica
else issues
in
let diff' =
diff
|> ( if Config.equal_analyzer Config.analyzer Config.BiAbduction then
skip_anonymous_class_renamings
else Fn.id )
diff |> (if Config.biabduction then skip_anonymous_class_renamings else Fn.id)
|> (if skip_duplicated_types then skip_duplicated_types_on_filenames renamings else Fn.id)
|> Fn.id
in

@ -112,14 +112,21 @@ let cluster_should_be_analyzed ~changed_files cluster =
| None
-> true
let register_active_checkers () =
match Config.analyzer with
| Checkers | Crashcontext
-> RegisterCheckers.get_active_checkers () |> RegisterCheckers.register
| BiAbduction | CaptureOnly | CompileOnly | Linters
-> ()
let main ~changed_files ~makefile =
BuiltinDefn.init () ;
RegisterCheckers.register () ;
( match Config.modified_targets with
| Some file
-> MergeCapture.record_modified_targets_from_file file
| None
-> () ) ;
register_active_checkers () ;
match Config.cluster_cmdline with
| Some fname
-> process_cluster_cmdline fname
@ -136,17 +143,16 @@ let main ~changed_files ~makefile =
else "" )
(if Int.equal n_clusters_to_analyze 1 then "" else "s")
Config.results_dir ;
let is_java () =
List.exists
let is_java =
( lazy
(List.exists
~f:(fun cl -> DB.string_crc_has_extension ~ext:"java" (DB.source_dir_to_string cl))
all_clusters
all_clusters) )
in
(if Config.print_active_checkers then L.result else L.debug Analysis Quiet)
"Active checkers: %a@\n" RegisterCheckers.pp_active_checkers () ;
L.debug Analysis Quiet "Dynamic dispatch mode: %s@."
Config.(string_of_dynamic_dispatch dynamic_dispatch) ;
print_legend () ;
if Config.per_procedure_parallelism && not (is_java ()) then (
if Config.per_procedure_parallelism && not (Lazy.force is_java) then (
(* Java uses ZipLib which is incompatible with forking *)
(* per-procedure parallelism *)
L.environment_info "Per-procedure parallelism jobs: %d@." Config.jobs ;

@ -43,15 +43,29 @@ let setup () =
| Explore
-> ResultsDir.assert_results_dir "please run an infer analysis first"
let print_active_checkers () =
(if Config.print_active_checkers && CLOpt.is_originator then L.result else L.environment_info)
"Analyzer: %s@."
Config.(string_of_analyzer analyzer) ;
(if Config.print_active_checkers && CLOpt.is_originator then L.result else L.environment_info)
"Active checkers: %a@." (Pp.seq ~sep:", " RegisterCheckers.pp_checker)
(RegisterCheckers.get_active_checkers ())
let log_environment_info () =
L.environment_info "CWD = %s@\n" (Sys.getcwd ()) ;
( match Config.inferconfig_file with
| Some file
-> L.environment_info "Read configuration in %s@\n" file
| None
-> L.environment_info "No .inferconfig file found@\n" ) ;
L.environment_info "Project root = %s@\n" Config.project_root ;
let infer_args =
Sys.getenv CLOpt.args_env_var |> Option.map ~f:(String.split ~on:CLOpt.env_var_sep)
|> Option.value ~default:["<not set>"]
in
L.environment_info "INFER_ARGS = %a" Pp.cli_args infer_args ;
L.environment_info "command line arguments: %a" Pp.cli_args (Array.to_list Sys.argv)
L.environment_info "command line arguments: %a" Pp.cli_args (Array.to_list Sys.argv) ;
print_active_checkers ()
let () =
( if Config.linters_validate_syntax_only then

@ -529,6 +529,10 @@ let exe_usage =
let anon_args = CLOpt.mk_anon ()
let all_checkers = ref []
let disable_all_checkers () = List.iter !all_checkers ~f:(fun (var, _, _, _) -> var := false)
let () =
let on_unknown_arg_from_command (cmd: CLOpt.command) =
match cmd with
@ -662,19 +666,16 @@ and ( annotation_reachability
, threadsafety
, suggest_nullable
, uninit ) =
let all_checkers = ref [] in
let default_checkers = ref [] in
let mk_checker ?(default= false) ~long doc =
let var = CLOpt.mk_bool ~long ~in_help:CLOpt.([(Analyze, manual_generic)]) ~default doc in
all_checkers := (var, long) :: !all_checkers ;
if default then default_checkers := (var, long) :: !default_checkers ;
all_checkers := (var, long, doc, default) :: !all_checkers ;
var
in
let annotation_reachability =
mk_checker ~default:true ~long:"annotation-reachability"
"the annotation reachability checker. Given a pair of source and sink annotation, e.g. @PerformanceCritical and @Expensive, this checker will warn whenever some method annotated with @PerformanceCritical calls, directly or indirectly, another method annotated with @Expensive"
and biabduction =
mk_checker ~long:"biabduction"
mk_checker ~long:"biabduction" ~default:true
"the separation logic based bi-abduction analysis using the checkers framework"
and bufferoverrun = mk_checker ~long:"bufferoverrun" "the buffer overrun analysis"
and check_nullable =
@ -696,27 +697,29 @@ and ( annotation_reachability
and printf_args =
mk_checker ~long:"printf-args" ~default:true
"the detection of mismatch between the Java printf format strings and the argument types For, example, this checker will warn about the type error in `printf(\"Hello %d\", \"world\")`"
and repeated_calls = mk_checker ~long:"repeated-calls" "check for repeated calls"
and quandary = mk_checker ~long:"quandary" ~default:true "the quandary taint analysis"
and repeated_calls = mk_checker ~long:"repeated-calls" "check for repeated calls"
and resource_leak = mk_checker ~long:"resource-leak" ""
and siof =
mk_checker ~long:"siof" ~default:true
"the Static Initialization Order Fiasco analysis (C++ only)"
and threadsafety = mk_checker ~long:"threadsafety" ~default:true "the thread safety analysis"
and suggest_nullable =
mk_checker ~long:"suggest-nullable" ~default:false
"Nullable annotation sugesstions analysis (experimental)"
mk_checker ~long:"suggest-nullable" ~default:false "Nullable annotation sugesstions analysis"
and threadsafety = mk_checker ~long:"threadsafety" ~default:true "the thread safety analysis"
and uninit = mk_checker ~long:"uninit" ~default:true "checker for use of uninitialized values" in
let mk_only (var, long) =
let mk_only (var, long, doc, _) =
let _ : bool ref =
CLOpt.mk_bool_group ~long:(long ^ "-only")
~in_help:CLOpt.([(Analyze, manual_generic)])
(Printf.sprintf "Enable $(b,--%s) and disable all other checkers" long)
[(* enable this checker *) var]
((* disable all checkers except this one *)
List.filter_map
~f:(fun (var', long') -> if String.equal long long' then None else Some var')
!all_checkers)
~f:(fun b ->
disable_all_checkers () ;
var := b ;
b)
( if String.equal doc "" then ""
else Printf.sprintf "Enable $(b,--%s) and disable all other checkers" long )
[] (* do all the work in ~f *)
[]
(* do all the work in ~f *)
in
()
in
@ -726,10 +729,20 @@ and ( annotation_reachability
~in_help:CLOpt.([(Analyze, manual_generic)])
~default:true
( "Default checkers: "
^ ( List.map ~f:(fun (_, s) -> Printf.sprintf "$(b,--%s)" s) !default_checkers
^ ( List.rev_filter_map
~f:(fun (_, long, _, default) ->
if default then Some (Printf.sprintf "$(b,--%s)" long) else None)
!all_checkers
|> String.concat ~sep:", " ) )
(List.map ~f:fst !default_checkers)
~f:(fun b ->
List.iter
~f:(fun (var, _, _, default) ->
var := if b then default || !var else not default && !var)
!all_checkers ;
b)
[] (* do all the work in ~f *)
[]
(* do all the work in ~f *)
in
( annotation_reachability
, biabduction
@ -1798,7 +1811,7 @@ and () = CLOpt.mk_set ~parse_mode:CLOpt.Javac version ~deprecated:["version"] ~l
(** Parse Command Line Args *)
let config_file =
let inferconfig_file =
let rec find dir =
match Sys.file_exists ~follow_symlinks:false (dir ^/ CommandDoc.inferconfig_file) with
| `Yes
@ -1845,7 +1858,7 @@ let post_parsing_initialization command_opt =
(match !analyzer with Some a -> a | None -> BiAbduction)
in
let infer_version =
match config_file with
match inferconfig_file with
| Some inferconfig
-> Printf.sprintf "version %s/inferconfig %s" Version.commit
(Digest.to_hex (Digest.file inferconfig))
@ -1933,28 +1946,29 @@ let post_parsing_initialization command_opt =
(* set analyzer mode to linters in linters developer mode *)
if !linters_developer_mode then analyzer := Some Linters ;
if !default_linters then linters_def_file := linters_def_default_file :: !linters_def_file ;
( match !analyzer with
| Some BiAbduction
-> biabduction := true
| Some Crashcontext
-> crashcontext := true
| Some (CaptureOnly | CompileOnly | Checkers | Linters)
-> ()
| None
-> let open CLOpt in
match command_opt with
( if Option.is_none !analyzer then
match (command_opt : CLOpt.command option) with
| Some Compile
-> analyzer := Some CompileOnly
| Some Capture
-> analyzer := Some CaptureOnly
| _
-> biabduction := true
(* the default option is to run the biabduction analysis *) ) ;
-> () ) ;
( match !analyzer with
| Some BiAbduction | None
-> disable_all_checkers () ;
(* technically the biabduction checker doesn't run in this mode, but this gives an easy way to test if the biabduction *analysis* is active *)
biabduction := true
| Some Crashcontext
-> disable_all_checkers () ;
crashcontext := true
| Some (CaptureOnly | Checkers | CompileOnly | Linters)
-> () ) ;
Option.value ~default:CLOpt.Run command_opt
let command, parse_args_and_return_usage_exit =
let command_opt, usage_exit =
CLOpt.parse ?config_file ~usage:exe_usage startup_action initial_command
CLOpt.parse ?config_file:inferconfig_file ~usage:exe_usage startup_action initial_command
in
let command = post_parsing_initialization command_opt in
(command, usage_exit)
@ -2462,10 +2476,7 @@ let dynamic_dispatch =
| BiAbduction
-> Lazy
| Checkers when biabduction
-> if quandary then
F.eprintf
"WARNING: Running Quandary on Java is not compatible with the Biabduction analysis@." ;
Lazy
-> Lazy
| Checkers when quandary
-> Sound
| _

@ -453,6 +453,8 @@ val infer_is_clang : bool
val infer_is_javac : bool
val inferconfig_file : string option
val iphoneos_target_sdk_version : string option
type iphoneos_target_sdk_version_path_regex = {path: Str.regexp; version: string}

@ -17,57 +17,90 @@ module F = Format
(* make sure SimpleChecker.ml is not dead code *)
let () = if false then let module SC = SimpleChecker.Make in ()
type callback =
type callback_fun =
| Procedure of Callbacks.proc_callback_t
| DynamicDispatch of Callbacks.proc_callback_t
| Cluster of Callbacks.cluster_callback_t
let checkers =
[ ( "annotation reachability"
, Config.annotation_reachability
, [(Procedure AnnotationReachability.checker, Config.Java)] )
; ( "biabduction"
, Config.biabduction
, [ (Procedure Interproc.analyze_procedure, Config.Clang)
; (DynamicDispatch Interproc.analyze_procedure, Config.Java) ] )
; ( "buffer overrun"
, Config.bufferoverrun
, [ (Procedure BufferOverrunChecker.checker, Config.Clang)
; (Procedure BufferOverrunChecker.checker, Config.Java) ] )
; ("crashcontext", Config.crashcontext, [(Procedure BoundedCallTree.checker, Config.Java)])
; ("eradicate", Config.eradicate, [(Procedure Eradicate.callback_eradicate, Config.Java)])
; ( "fragment retains view"
, Config.fragment_retains_view
, [(Procedure FragmentRetainsViewChecker.callback_fragment_retains_view, Config.Java)] )
; ( "immutable cast"
, Config.immutable_cast
, [(Procedure ImmutableChecker.callback_check_immutable_cast, Config.Java)] )
; ("liveness", Config.liveness, [(Procedure Liveness.checker, Config.Clang)])
; ("printf args", Config.printf_args, [(Procedure PrintfArgs.callback_printf_args, Config.Java)])
; ( "nullable suggestion"
, Config.suggest_nullable
, [ (Procedure NullabilitySuggest.checker, Config.Java)
; (Procedure NullabilitySuggest.checker, Config.Clang) ] )
; ("nullable checks", Config.check_nullable, [(Procedure NullabilityCheck.checker, Config.Clang)])
; ( "quandary"
, Config.quandary
, [ (Procedure JavaTaintAnalysis.checker, Config.Java)
; (Procedure ClangTaintAnalysis.checker, Config.Clang) ] )
; ( "repeated calls"
, Config.repeated_calls
, [(Procedure RepeatedCallsChecker.callback_check_repeated_calls, Config.Java)] )
; ("resource leak", Config.resource_leak, [(Procedure ResourceLeaks.checker, Config.Java)])
; ("SIOF", Config.siof, [(Procedure Siof.checker, Config.Clang)])
; ("uninitialized variables", Config.uninit, [(Procedure Uninit.checker, Config.Clang)])
; ( "thread safety"
, Config.threadsafety
, [ (Procedure ThreadSafety.analyze_procedure, Config.Clang)
type callback = callback_fun * Config.language
type checker = {name: string; active: bool; callbacks: callback list}
let all_checkers =
[ { name= "annotation reachability"
; active= Config.annotation_reachability
; callbacks= [(Procedure AnnotationReachability.checker, Config.Java)] }
; { name= "biabduction"
; active= Config.biabduction
; callbacks=
[ (Procedure Interproc.analyze_procedure, Config.Clang)
; (DynamicDispatch Interproc.analyze_procedure, Config.Java) ] }
; { name= "buffer overrun"
; active= Config.bufferoverrun
; callbacks=
[ (Procedure BufferOverrunChecker.checker, Config.Clang)
; (Procedure BufferOverrunChecker.checker, Config.Java) ] }
; { name= "crashcontext"
; active= Config.crashcontext
; callbacks= [(Procedure BoundedCallTree.checker, Config.Java)] }
; { name= "eradicate"
; active= Config.eradicate
; callbacks= [(Procedure Eradicate.callback_eradicate, Config.Java)] }
; { name= "fragment retains view"
; active= Config.fragment_retains_view
; callbacks=
[(Procedure FragmentRetainsViewChecker.callback_fragment_retains_view, Config.Java)] }
; { name= "immutable cast"
; active= Config.immutable_cast
; callbacks= [(Procedure ImmutableChecker.callback_check_immutable_cast, Config.Java)] }
; { name= "liveness"
; active= Config.liveness
; callbacks= [(Procedure Liveness.checker, Config.Clang)] }
; { name= "printf args"
; active= Config.printf_args
; callbacks= [(Procedure PrintfArgs.callback_printf_args, Config.Java)] }
; { name= "nullable checks"
; active= Config.check_nullable
; callbacks= [(Procedure NullabilityCheck.checker, Config.Clang)] }
; { name= "nullable suggestion"
; active= Config.suggest_nullable
; callbacks=
[ (Procedure NullabilitySuggest.checker, Config.Java)
; (Procedure NullabilitySuggest.checker, Config.Clang) ] }
; { name= "quandary"
; active= Config.quandary
; callbacks=
[ (Procedure JavaTaintAnalysis.checker, Config.Java)
; (Procedure ClangTaintAnalysis.checker, Config.Clang) ] }
; { name= "repeated calls"
; active= Config.repeated_calls
; callbacks= [(Procedure RepeatedCallsChecker.callback_check_repeated_calls, Config.Java)] }
; { name=
"resource leak"
(** toy resource analysis to use in the infer lab, see the lab/ directory *)
; active= Config.resource_leak
; callbacks=
[ ( (* the checked-in version is intraprocedural, but the lab asks to make it interprocedural later on *)
Procedure ResourceLeaks.checker
, Config.Java ) ] }
; {name= "SIOF"; active= Config.siof; callbacks= [(Procedure Siof.checker, Config.Clang)]}
; { name= "thread safety"
; active= Config.threadsafety
; callbacks=
[ (Procedure ThreadSafety.analyze_procedure, Config.Clang)
; (Procedure ThreadSafety.analyze_procedure, Config.Java)
; (Cluster ThreadSafety.file_analysis, Config.Clang)
; (Cluster ThreadSafety.file_analysis, Config.Java) ] ) ]
; (Cluster ThreadSafety.file_analysis, Config.Java) ] }
; { name= "uninitialized variables"
; active= Config.uninit
; callbacks= [(Procedure Uninit.checker, Config.Clang)] } ]
let get_active_checkers () =
let filter_checker {active} = active in
List.filter ~f:filter_checker all_checkers
let register () =
let register_one (_, active, callbacks) =
let register checkers =
let register_one {callbacks} =
let register_callback (callback, language) =
match callback with
| Procedure procedure_cb
@ -77,14 +110,22 @@ let register () =
| Cluster cluster_cb
-> Callbacks.register_cluster_callback language cluster_cb
in
if active then List.iter ~f:register_callback callbacks
List.iter ~f:register_callback callbacks
in
List.iter ~f:register_one checkers
let pp_active_checkers fmt () =
let has_active = ref false in
List.iter checkers ~f:(fun (name, active, _) ->
if active then (
Format.fprintf fmt "%s%s" (if !has_active then ", " else "") name ;
has_active := true ) ) ;
if not !has_active then Format.fprintf fmt "none"
module LanguageSet = Caml.Set.Make (struct
type t = Config.language
let compare = Config.compare_language
end)
let pp_checker fmt {name; callbacks} =
let langs_of_callbacks =
List.fold_left callbacks ~init:LanguageSet.empty ~f:(fun langs (_, lang) ->
LanguageSet.add lang langs )
|> LanguageSet.elements
in
F.fprintf fmt "%s (%a)" name
(Pp.seq ~sep:", " (Pp.to_string ~f:Config.string_of_language))
langs_of_callbacks

@ -9,6 +9,10 @@
open! IStd
val register : unit -> unit
type checker
val pp_active_checkers : Format.formatter -> unit -> unit
val get_active_checkers : unit -> checker list
val register : checker list -> unit
val pp_checker : Format.formatter -> checker -> unit

@ -18,7 +18,7 @@ INFERPRINT_OPTIONS = --issues-tests
include $(TESTS_DIR)/java.make
include $(TESTS_DIR)/infer.make
infer-out/report.json: $(JAVA_DEPS) $(SOURCES)
infer-out/report.json: $(JAVA_DEPS) $(SOURCES) $(MAKEFILE_LIST)
# mock version of gradle
$(QUIET)PATH=$(CURDIR)/../mock:"$$PATH"; \
cd $(SOURCES_DIR) && \

@ -17,7 +17,7 @@ default: analyze
.PHONY: analyze
analyze: $(REPORT)
$(REPORT):
$(REPORT): $(JAVA_DEPS) $(MAKEFILE_LIST) SimpleLeak.java
$(QUIET)$(call silent_on_success,Running analysis,\
$(INFER_BIN) -o $(INFER_OUT) --project-root $(CURDIR) -- javac SimpleLeak.java)

@ -10,7 +10,7 @@ TESTS_DIR = ../../..
ANALYZER = checkers
# see explanations in cpp/errors/Makefile for the custom isystem
CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(ROOT_DIR) -isystem$(CLANG_INCLUDES)/c++/v1/ -c
INFER_OPTIONS = --threadsafety --ml-buckets cpp --no-filtering --debug-exceptions --project-root $(TESTS_DIR)
INFER_OPTIONS = --threadsafety-only --debug-exceptions --project-root $(TESTS_DIR)
INFERPRINT_OPTIONS = --issues-tests
SOURCES = $(wildcard *.cpp)

@ -10,7 +10,7 @@ TESTS_DIR = ../../..
ANALYZER = checkers
# see explanations in cpp/errors/Makefile for the custom isystem
CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(MODELS_DIR)/cpp/include -isystem$(CLANG_INCLUDES)/c++/v1/ -c
INFER_OPTIONS = --uninit --ml-buckets cpp --no-filtering --debug-exceptions --project-root $(TESTS_DIR)
INFER_OPTIONS = --uninit-only --debug-exceptions --project-root $(TESTS_DIR)
INFERPRINT_OPTIONS = --issues-tests
SOURCES = uninit.cpp

@ -1,5 +1,5 @@
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":24,"blame_range":[{"start_line":22,"end_line":25}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":29,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":22,"blame_range":[{"start_line":22,"end_line":25}]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.pre_bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":14,"blame_range":[{"start_line":14,"end_line":15}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":34,"blame_range":[{"start_line":33,"end_line":34}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":27,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":18,"blame_range":[{"start_line":16,"end_line":19}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":16,"blame_range":[{"start_line":16,"end_line":19}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":32,"blame_range":[{"start_line":31,"end_line":32}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MinimalCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MinimalCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":17}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":17}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":20,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":14,"blame_range":[{"start_line":14,"end_line":17}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":24,"blame_range":[{"start_line":23,"end_line":24}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":19,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.foo():void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":18,"blame_range":[{"start_line":16,"end_line":19}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke0","location":{"location_type":"call_site","file":"Native Method","blame_range":[]},"callees":[]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"NativeMethodAccessorImpl.java","line":62,"blame_range":[]},"callees":[]},{"method_name":"sun.reflect.DelegatingMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"DelegatingMethodAccessorImpl.java","line":43,"blame_range":[]},"callees":[]},{"method_name":"java.lang.reflect.Method.invoke","location":{"location_type":"call_site","file":"Method.java","line":497,"blame_range":[]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":27,"blame_range":[{"start_line":21,"end_line":31}]},"callees":[{"method_name":"java.lang.Class.getDeclaredMethod(java.lang.String,java.lang.Class[]):java.lang.reflect.Method","callees":[]},{"method_name":"java.lang.reflect.Method.invoke(java.lang.Object,java.lang.Object[]):java.lang.Object","callees":[]},{"method_name":"__new_array","callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":24,"blame_range":[{"start_line":22,"end_line":24}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":29,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":22,"blame_range":[{"start_line":22,"end_line":24}]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.pre_bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":14,"blame_range":[{"start_line":14,"end_line":15}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":34,"blame_range":[{"start_line":33,"end_line":34}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":27,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":18,"blame_range":[{"start_line":16,"end_line":18}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":16,"blame_range":[{"start_line":16,"end_line":18}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":32,"blame_range":[{"start_line":31,"end_line":32}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MinimalCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MinimalCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":16}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":16}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":20,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":14,"blame_range":[{"start_line":14,"end_line":16}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":24,"blame_range":[{"start_line":23,"end_line":24}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":19,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[]}]}]}
{"stack":[{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.foo():void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":18,"blame_range":[{"start_line":16,"end_line":18}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke0","location":{"location_type":"call_site","file":"Native Method","blame_range":[]},"callees":[]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"NativeMethodAccessorImpl.java","line":62,"blame_range":[]},"callees":[]},{"method_name":"sun.reflect.DelegatingMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"DelegatingMethodAccessorImpl.java","line":43,"blame_range":[]},"callees":[]},{"method_name":"java.lang.reflect.Method.invoke","location":{"location_type":"call_site","file":"Method.java","line":497,"blame_range":[]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":27,"blame_range":[{"start_line":21,"end_line":29}]},"callees":[{"method_name":"java.lang.Class.getDeclaredMethod(java.lang.String,java.lang.Class[]):java.lang.reflect.Method","callees":[]},{"method_name":"java.lang.reflect.Method.invoke(java.lang.Object,java.lang.Object[]):java.lang.Object","callees":[]},{"method_name":"__new_array","callees":[]}]}]}

Loading…
Cancel
Save