[Makefile] Print duplicate symbols to separate file, not stderr

Summary:
All tests were redirecting `stderr` into duplicates.txt which made it much harder to see other error messages in stderr (such as uncaught exceptions).
To mitigate it, write duplicates to separate file and don't redirect `stderr` to another file.

Reviewed By: jvillard

Differential Revision: D4728938

fbshipit-source-id: 8ad2fc8
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent 86656b2db0
commit d4e9f0de64

@ -15,6 +15,7 @@ module Hashtbl = Caml.Hashtbl
(** Support for Execution environments *) (** Support for Execution environments *)
module L = Logging module L = Logging
module F = Format
(** per-file data: type environment and cfg *) (** per-file data: type environment and cfg *)
type file_data = type file_data =
@ -91,24 +92,29 @@ let add_cg (exe_env: t) (source_dir : DB.source_dir) =
let source = Cg.get_source cg in let source = Cg.get_source cg in
exe_env.source_files <- SourceFile.Set.add source exe_env.source_files; exe_env.source_files <- SourceFile.Set.add source exe_env.source_files;
let defined_procs = Cg.get_defined_nodes cg in let defined_procs = Cg.get_defined_nodes cg in
let duplicate_procs_to_print = List.filter_map defined_procs
List.iter ~f:(fun pname ->
~f:(fun pname -> (match AttributesTable.find_file_capturing_procedure ~cache:false pname with
(match AttributesTable.find_file_capturing_procedure ~cache:false pname with | None -> None
| None -> | Some (source_captured, origin) ->
() let multiply_defined = SourceFile.compare source source_captured <> 0 in
| Some (source_captured, origin) -> if multiply_defined then Cg.remove_node_defined cg pname;
let multiply_defined = SourceFile.compare source source_captured <> 0 in if multiply_defined && origin <> `Include then
if multiply_defined then Cg.remove_node_defined cg pname; Some (pname, source_captured)
if Config.check_duplicate_symbols && else None
multiply_defined && )) in
origin <> `Include then (if Config.dump_duplicate_symbols then
L.stderr "@.DUPLICATE_SYMBOLS source: %a source_captured:%a pname:%a@." Out_channel.with_file (Config.results_dir ^/ Config.duplicates_filename)
~append:true ~perm:0o666 ~f:(fun outc ->
let fmt = F.formatter_of_out_channel outc in
List.iter duplicate_procs_to_print ~f:(fun (pname, source_captured) ->
F.fprintf fmt "@.DUPLICATE_SYMBOLS source: %a source_captured:%a pname:%a@."
SourceFile.pp source SourceFile.pp source
SourceFile.pp source_captured SourceFile.pp source_captured
Typ.Procname.pp pname Typ.Procname.pp pname
)) );
defined_procs; )
);
Cg.extend exe_env.cg cg Cg.extend exe_env.cg cg
(** get the global call graph *) (** get the global call graph *)

@ -161,6 +161,15 @@ let register_perf_stats_report () =
Unix.mkdir_p stats_dir; Unix.mkdir_p stats_dir;
PerfStats.register_report_at_exit stats_file PerfStats.register_report_at_exit stats_file
let reset_duplicates_file () =
let start = Config.results_dir ^/ Config.duplicates_filename in
let delete () =
Unix.unlink start in
let create () =
Unix.close (Unix.openfile ~perm:0o0666 ~mode:[Unix.O_CREAT; Unix.O_WRONLY] start) in
if Sys.file_exists start = `Yes then delete ();
create ()
(* Create the .start file, and update the timestamp unless in continue mode *) (* Create the .start file, and update the timestamp unless in continue mode *)
let touch_start_file_unless_continue () = let touch_start_file_unless_continue () =
let start = Config.results_dir ^/ Config.start_filename in let start = Config.results_dir ^/ Config.start_filename in
@ -450,6 +459,7 @@ let infer_mode () =
if Config.print_builtins then Builtin.print_and_exit () ; if Config.print_builtins then Builtin.print_and_exit () ;
if CLOpt.is_originator then L.do_out "%s@\n" Config.version_string ; if CLOpt.is_originator then L.do_out "%s@\n" Config.version_string ;
if Config.debug_mode || Config.stats_mode then log_infer_args driver_mode ; if Config.debug_mode || Config.stats_mode then log_infer_args driver_mode ;
if Config.dump_duplicate_symbols then reset_duplicates_file ();
(* infer might be called from a Makefile and itself uses `make` to run the analysis in parallel, (* infer might be called from a Makefile and itself uses `make` to run the analysis in parallel,
but cannot communicate with the parent make command. Since infer won't interfere with them but cannot communicate with the parent make command. Since infer won't interfere with them
anyway, pretend that we are not called from another make to prevent make falling back to a anyway, pretend that we are not called from another make to prevent make falling back to a

@ -144,6 +144,8 @@ let default_in_zip_results_dir = "infer"
(** Dotty output filename **) (** Dotty output filename **)
let dotty_output = "icfg.dot" let dotty_output = "icfg.dot"
let duplicates_filename = "duplicates.txt"
(** exit code to use for the --fail-on-issue option *) (** exit code to use for the --fail-on-issue option *)
let fail_on_issue_exit_code = 2 let fail_on_issue_exit_code = 2
@ -619,11 +621,6 @@ and changed_files_index =
"Specify the file containing the list of source files from which reactive analysis should \ "Specify the file containing the list of source files from which reactive analysis should \
start. Source files should be specified relative to project root or be absolute" start. Source files should be specified relative to project root or be absolute"
and check_duplicate_symbols =
CLOpt.mk_bool ~long:"check-duplicate-symbols"
~parse_mode:CLOpt.(Infer [Clang])
"Check if a symbol with the same name is defined in more than one file."
and checkers, crashcontext, eradicate, quandary, threadsafety, bufferoverrun = and checkers, crashcontext, eradicate, quandary, threadsafety, bufferoverrun =
let checkers = let checkers =
CLOpt.mk_bool ~deprecated:["checkers"] ~long:"checkers" CLOpt.mk_bool ~deprecated:["checkers"] ~long:"checkers"
@ -833,6 +830,10 @@ and dotty_cfg_libs =
CLOpt.mk_bool ~deprecated:["dotty_no_cfg_libs"] ~long:"dotty-cfg-libs" ~default:true CLOpt.mk_bool ~deprecated:["dotty_no_cfg_libs"] ~long:"dotty-cfg-libs" ~default:true
"Print the cfg of the code coming from the libraries" "Print the cfg of the code coming from the libraries"
and dump_duplicate_symbols =
CLOpt.mk_bool ~long:"dump-duplicate-symbols" ~parse_mode:CLOpt.(Infer [Clang])
"Dump all symbols with the same name that are defined in more than one file."
and dynamic_dispatch = and dynamic_dispatch =
CLOpt.mk_symbol_opt ~long:"dynamic-dispatch" CLOpt.mk_symbol_opt ~long:"dynamic-dispatch"
"Specify treatment of dynamic dispatch in Java code: 'none' treats dynamic dispatch as a call \ "Specify treatment of dynamic dispatch in Java code: 'none' treats dynamic dispatch as a call \
@ -1584,7 +1585,7 @@ and bugs_txt = !bugs_txt
and bugs_xml = !bugs_xml and bugs_xml = !bugs_xml
and changed_files_index = !changed_files_index and changed_files_index = !changed_files_index
and calls_csv = !calls_csv and calls_csv = !calls_csv
and check_duplicate_symbols = !check_duplicate_symbols and dump_duplicate_symbols = !dump_duplicate_symbols
and checkers = !checkers and checkers = !checkers
and checkers_repeated_calls = !checkers_repeated_calls and checkers_repeated_calls = !checkers_repeated_calls
and clang_biniou_file = !clang_biniou_file and clang_biniou_file = !clang_biniou_file

@ -88,6 +88,7 @@ val checks_disabled_by_default : string list
val clang_initializer_prefix : string val clang_initializer_prefix : string
val classpath : string option val classpath : string option
val cpp_extra_include_dir : string val cpp_extra_include_dir : string
val duplicates_filename : string
val relative_cpp_models_dir : string val relative_cpp_models_dir : string
val csl_analysis : bool val csl_analysis : bool
val default_failure_name : string val default_failure_name : string
@ -186,7 +187,6 @@ val bugs_txt : string option
val bugs_xml : string option val bugs_xml : string option
val changed_files_index : string option val changed_files_index : string option
val calls_csv : string option val calls_csv : string option
val check_duplicate_symbols : bool
val checkers : bool val checkers : bool
val checkers_enabled : bool val checkers_enabled : bool
val checkers_repeated_calls : bool val checkers_repeated_calls : bool
@ -209,6 +209,7 @@ val dependency_mode : bool
val developer_mode : bool val developer_mode : bool
val disable_checks : string list val disable_checks : string list
val dotty_cfg_libs : bool val dotty_cfg_libs : bool
val dump_duplicate_symbols : bool
val dynamic_dispatch : [ `None | `Interface | `Sound | `Lazy ] val dynamic_dispatch : [ `None | `Interface | `Sound | `Lazy ]
val enable_checks : string list val enable_checks : string list
val eradicate : bool val eradicate : bool

@ -24,8 +24,8 @@ include $(TESTS_DIR)/clang.make
infer-out/report.json: $(CLANG_DEPS) $(SOURCES) infer-out/report.json: $(CLANG_DEPS) $(SOURCES)
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello.c 2>duplicates.txt) $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello.c)
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello2.c 2>duplicates.txt) $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello2.c)
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0

@ -18,6 +18,6 @@ include $(TESTS_DIR)/clang.make
infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS)
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols --project-root $(TESTS_DIR) -a $(ANALYZER) -- \ $(INFER_BIN) --dump-duplicate-symbols --project-root $(TESTS_DIR) -a $(ANALYZER) -- \
make -C ../codetoanalyze/make clean all 2>duplicates.txt) make -C ../codetoanalyze/make clean all)
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0

@ -31,5 +31,5 @@ infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS)
$(INFER_BIN) $(INFER_OPTIONS) -a capture --reactive --continue -- \ $(INFER_BIN) $(INFER_OPTIONS) -a capture --reactive --continue -- \
clang $(CLANG_OPTIONS) $(SOURCES3)) clang $(CLANG_OPTIONS) $(SOURCES3))
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- analyze 2>duplicates.txt) $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- analyze)
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0

@ -21,8 +21,8 @@ infer-out/report.json: $(CLANG_DEPS) $(INFERTRACEBUGS_BIN) $(SOURCES) $(HEADERS)
# set non-utf8-supporting locale # set non-utf8-supporting locale
LC_ALL=C; \ LC_ALL=C; \
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES) 2>duplicates.txt) $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES))
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0
# make sure inferTraceBugs is immune to UTF-8 # make sure inferTraceBugs is immune to UTF-8
$(call silent_on_success, $(INFERTRACEBUGS_BIN) --max-level max --select 0) $(call silent_on_success, $(INFERTRACEBUGS_BIN) --max-level max --select 0)
$(call silent_on_success, $(INFERTRACEBUGS_BIN) --html) $(call silent_on_success, $(INFERTRACEBUGS_BIN) --html)
@ -30,5 +30,5 @@ infer-out/report.json: $(CLANG_DEPS) $(INFERTRACEBUGS_BIN) $(SOURCES) $(HEADERS)
# run again to check that infer manages to delete the results directory # run again to check that infer manages to delete the results directory
LC_ALL=C; \ LC_ALL=C; \
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES) 2>duplicates.txt) $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES))
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0

@ -21,5 +21,5 @@ infer-out/report.json: $(CLANG_DEPS) $(SOURCES)
$(MAKE) -C ../codetoanalyze/make clean $(MAKE) -C ../codetoanalyze/make clean
cd ../codetoanalyze/make && \ cd ../codetoanalyze/make && \
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --check-duplicate-symbols --results-dir $(CUR_DIR)/$(@D) -a $(ANALYZER) -- \ $(INFER_BIN) --dump-duplicate-symbols --results-dir $(CUR_DIR)/$(@D) -a $(ANALYZER) -- \
./waf) ./waf)

@ -16,8 +16,7 @@ include $(TESTS_DIR)/clang-base.make
infer-out$(TEST_SUFFIX)/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(TESTS_DIR)/.inferconfig infer-out$(TEST_SUFFIX)/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(TESTS_DIR)/.inferconfig
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) --results-dir $(@D) --check-duplicate-symbols \ $(INFER_BIN) --results-dir $(@D) --dump-duplicate-symbols \
$(INFER_OPTIONS) -a $(ANALYZER) -- \ $(INFER_OPTIONS) -a $(ANALYZER) -- \
clang $(CLANG_OPTIONS) $(SOURCES) 2> \ clang $(CLANG_OPTIONS) $(SOURCES))
>(tee duplicates.txt)) grep "DUPLICATE_SYMBOLS" infer-out$(TEST_SUFFIX)/duplicates.txt; test $$? -ne 0
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0

@ -11,17 +11,17 @@
extern SomeTemplatedNonPODObject<int> extern_global_object; extern SomeTemplatedNonPODObject<int> extern_global_object;
SomeTemplatedNonPODObject<int> global_object; SomeTemplatedNonPODObject<int> global_template_object;
template <typename T> template <typename T>
struct SomeOtherTemplatedNonPODObject { struct SomeOtherTemplatedNonPODObject {
SomeOtherTemplatedNonPODObject() { SomeOtherTemplatedNonPODObject() {
global_object.some_method(); // OK, same translation unit global_template_object.some_method(); // OK, same translation unit
extern_global_object.some_method(); // bad, different translation unit extern_global_object.some_method(); // bad, different translation unit
}; };
SomeOtherTemplatedNonPODObject(int i) { SomeOtherTemplatedNonPODObject(int i) {
global_object.some_method(); // OK, same translation unit global_template_object.some_method(); // OK, same translation unit
}; };
}; };

@ -18,7 +18,7 @@ CLANG_OPTIONS = -x objective-c \
CLEAN_EXTRA = infer-out-arc infer-out-all infer-out-all infer-out-arc \ CLEAN_EXTRA = infer-out-arc infer-out-all infer-out-all infer-out-arc \
issues.exp.test.all issues.exp.test.arc issues.exp.test.default issues.exp.test.all issues.exp.test.arc issues.exp.test.default
INFER_OPTIONS = --check-duplicate-symbols --no-filtering --debug-exceptions --project-root $(TESTS_DIR) --no-failures-allowed INFER_OPTIONS = --dump-duplicate-symbols --no-filtering --debug-exceptions --project-root $(TESTS_DIR) --no-failures-allowed
INFERPRINT_OPTIONS = --issues-tests INFERPRINT_OPTIONS = --issues-tests
SOURCES_DEFAULT = \ SOURCES_DEFAULT = \
@ -117,20 +117,20 @@ $(OBJECTS_BASE) $(OBJECTS_BUCKETS_ALL): $(SOURCES_BASE) $(SOURCES_BUCKET_ALL)
infer-out-all/report.json: $(CLANG_DEPS) $(SOURCES_BUCKET_ALL) infer-out-all/report.json: $(CLANG_DEPS) $(SOURCES_BUCKET_ALL)
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets all -o infer-out-all -- \ $(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets all -o infer-out-all -- \
clang $(CLANG_OPTIONS) $(SOURCES_BUCKET_ALL) 2>duplicates.txt) clang $(CLANG_OPTIONS) $(SOURCES_BUCKET_ALL))
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out-all/duplicates.txt; test $$? -ne 0
infer-out-arc/report.json: $(CLANG_DEPS) $(SOURCES_ARC) infer-out-arc/report.json: $(CLANG_DEPS) $(SOURCES_ARC)
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets cf -o infer-out-arc -- \ $(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets cf -o infer-out-arc -- \
clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC) 2>duplicates.txt) clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC))
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out-arc/duplicates.txt; test $$? -ne 0
infer-out/report.json: $(CLANG_DEPS) $(SOURCES_DEFAULT) infer-out/report.json: $(CLANG_DEPS) $(SOURCES_DEFAULT)
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets cf -o infer-out -- \ $(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets cf -o infer-out -- \
clang $(CLANG_OPTIONS) $(SOURCES_DEFAULT) 2>duplicates.txt) clang $(CLANG_OPTIONS) $(SOURCES_DEFAULT))
grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0
issues.exp.test: infer-out-all/report.json infer-out-arc/report.json infer-out/report.json issues.exp.test: infer-out-all/report.json infer-out-arc/report.json infer-out/report.json
$(INFERPRINT_BIN) -q -a $(ANALYZER) $(INFERPRINT_OPTIONS) $@.all \ $(INFERPRINT_BIN) -q -a $(ANALYZER) $(INFERPRINT_OPTIONS) $@.all \

Loading…
Cancel
Save