From d4e9f0de64e5e83746adeb45dbb971d3bc35ca29 Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Tue, 21 Mar 2017 07:18:00 -0700 Subject: [PATCH] [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 --- infer/src/backend/exe_env.ml | 36 +++++++++++-------- infer/src/backend/infer.ml | 10 ++++++ infer/src/base/Config.ml | 13 +++---- infer/src/base/Config.mli | 3 +- .../build_systems/delete_results_dir/Makefile | 8 ++--- infer/tests/build_systems/make/Makefile | 6 ++-- infer/tests/build_systems/reactive/Makefile | 4 +-- .../build_systems/utf8_in_procname/Makefile | 8 ++--- infer/tests/build_systems/waf/Makefile | 2 +- infer/tests/clang.make | 7 ++-- .../cpp/checkers/siof/siof_templated.cpp | 6 ++-- .../tests/codetoanalyze/objc/errors/Makefile | 14 ++++---- 12 files changed, 67 insertions(+), 50 deletions(-) diff --git a/infer/src/backend/exe_env.ml b/infer/src/backend/exe_env.ml index 726bd5cd6..e4ff79090 100644 --- a/infer/src/backend/exe_env.ml +++ b/infer/src/backend/exe_env.ml @@ -15,6 +15,7 @@ module Hashtbl = Caml.Hashtbl (** Support for Execution environments *) module L = Logging +module F = Format (** per-file data: type environment and cfg *) 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 exe_env.source_files <- SourceFile.Set.add source exe_env.source_files; let defined_procs = Cg.get_defined_nodes cg in - - List.iter - ~f:(fun pname -> - (match AttributesTable.find_file_capturing_procedure ~cache:false pname with - | None -> - () - | Some (source_captured, origin) -> - let multiply_defined = SourceFile.compare source source_captured <> 0 in - if multiply_defined then Cg.remove_node_defined cg pname; - if Config.check_duplicate_symbols && - multiply_defined && - origin <> `Include then - L.stderr "@.DUPLICATE_SYMBOLS source: %a source_captured:%a pname:%a@." + let duplicate_procs_to_print = List.filter_map defined_procs + ~f:(fun pname -> + (match AttributesTable.find_file_capturing_procedure ~cache:false pname with + | None -> None + | Some (source_captured, origin) -> + let multiply_defined = SourceFile.compare source source_captured <> 0 in + if multiply_defined then Cg.remove_node_defined cg pname; + if multiply_defined && origin <> `Include then + Some (pname, source_captured) + else None + )) in + (if Config.dump_duplicate_symbols then + 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_captured Typ.Procname.pp pname - )) - defined_procs; + ); + ) + ); Cg.extend exe_env.cg cg (** get the global call graph *) diff --git a/infer/src/backend/infer.ml b/infer/src/backend/infer.ml index 4e8a0c52a..fb38458cb 100644 --- a/infer/src/backend/infer.ml +++ b/infer/src/backend/infer.ml @@ -161,6 +161,15 @@ let register_perf_stats_report () = Unix.mkdir_p stats_dir; 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 *) let touch_start_file_unless_continue () = 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 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.dump_duplicate_symbols then reset_duplicates_file (); (* 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 anyway, pretend that we are not called from another make to prevent make falling back to a diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 0d451f0cb..d40be42b0 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -144,6 +144,8 @@ let default_in_zip_results_dir = "infer" (** Dotty output filename **) let dotty_output = "icfg.dot" +let duplicates_filename = "duplicates.txt" + (** exit code to use for the --fail-on-issue option *) 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 \ 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 = let 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 "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 = CLOpt.mk_symbol_opt ~long:"dynamic-dispatch" "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 changed_files_index = !changed_files_index and calls_csv = !calls_csv -and check_duplicate_symbols = !check_duplicate_symbols +and dump_duplicate_symbols = !dump_duplicate_symbols and checkers = !checkers and checkers_repeated_calls = !checkers_repeated_calls and clang_biniou_file = !clang_biniou_file diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 4446083f0..f95ff7877 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -88,6 +88,7 @@ val checks_disabled_by_default : string list val clang_initializer_prefix : string val classpath : string option val cpp_extra_include_dir : string +val duplicates_filename : string val relative_cpp_models_dir : string val csl_analysis : bool val default_failure_name : string @@ -186,7 +187,6 @@ val bugs_txt : string option val bugs_xml : string option val changed_files_index : string option val calls_csv : string option -val check_duplicate_symbols : bool val checkers : bool val checkers_enabled : bool val checkers_repeated_calls : bool @@ -209,6 +209,7 @@ val dependency_mode : bool val developer_mode : bool val disable_checks : string list val dotty_cfg_libs : bool +val dump_duplicate_symbols : bool val dynamic_dispatch : [ `None | `Interface | `Sound | `Lazy ] val enable_checks : string list val eradicate : bool diff --git a/infer/tests/build_systems/delete_results_dir/Makefile b/infer/tests/build_systems/delete_results_dir/Makefile index 2bacaa5f8..08ec65135 100644 --- a/infer/tests/build_systems/delete_results_dir/Makefile +++ b/infer/tests/build_systems/delete_results_dir/Makefile @@ -24,8 +24,8 @@ include $(TESTS_DIR)/clang.make infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(call silent_on_success,\ - $(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello.c 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello.c) + grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0 $(call silent_on_success,\ - $(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello2.c 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(CODETOANALYZE_DIR)/hello2.c) + grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0 diff --git a/infer/tests/build_systems/make/Makefile b/infer/tests/build_systems/make/Makefile index acdf4e32c..6178d851f 100644 --- a/infer/tests/build_systems/make/Makefile +++ b/infer/tests/build_systems/make/Makefile @@ -18,6 +18,6 @@ include $(TESTS_DIR)/clang.make infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(call silent_on_success,\ - $(INFER_BIN) --check-duplicate-symbols --project-root $(TESTS_DIR) -a $(ANALYZER) -- \ - make -C ../codetoanalyze/make clean all 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) --dump-duplicate-symbols --project-root $(TESTS_DIR) -a $(ANALYZER) -- \ + make -C ../codetoanalyze/make clean all) + grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0 diff --git a/infer/tests/build_systems/reactive/Makefile b/infer/tests/build_systems/reactive/Makefile index 5bb8d424a..e22d0716f 100644 --- a/infer/tests/build_systems/reactive/Makefile +++ b/infer/tests/build_systems/reactive/Makefile @@ -31,5 +31,5 @@ infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(INFER_BIN) $(INFER_OPTIONS) -a capture --reactive --continue -- \ clang $(CLANG_OPTIONS) $(SOURCES3)) $(call silent_on_success,\ - $(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- analyze 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- analyze) + grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0 diff --git a/infer/tests/build_systems/utf8_in_procname/Makefile b/infer/tests/build_systems/utf8_in_procname/Makefile index 18a85f049..951e1f8e9 100644 --- a/infer/tests/build_systems/utf8_in_procname/Makefile +++ b/infer/tests/build_systems/utf8_in_procname/Makefile @@ -21,8 +21,8 @@ infer-out/report.json: $(CLANG_DEPS) $(INFERTRACEBUGS_BIN) $(SOURCES) $(HEADERS) # set non-utf8-supporting locale LC_ALL=C; \ $(call silent_on_success,\ - $(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES) 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES)) + grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0 # 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) --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 LC_ALL=C; \ $(call silent_on_success,\ - $(INFER_BIN) --check-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES) 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) --dump-duplicate-symbols $(INFER_OPTIONS) -a $(ANALYZER) -- clang $(CLANG_OPTIONS) $(SOURCES)) + grep "DUPLICATE_SYMBOLS" infer-out/duplicates.txt; test $$? -ne 0 diff --git a/infer/tests/build_systems/waf/Makefile b/infer/tests/build_systems/waf/Makefile index 69294213f..4bda6ec3a 100644 --- a/infer/tests/build_systems/waf/Makefile +++ b/infer/tests/build_systems/waf/Makefile @@ -21,5 +21,5 @@ infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(MAKE) -C ../codetoanalyze/make clean cd ../codetoanalyze/make && \ $(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) diff --git a/infer/tests/clang.make b/infer/tests/clang.make index 0cde10e34..4912c1f05 100644 --- a/infer/tests/clang.make +++ b/infer/tests/clang.make @@ -16,8 +16,7 @@ include $(TESTS_DIR)/clang-base.make infer-out$(TEST_SUFFIX)/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(TESTS_DIR)/.inferconfig $(call silent_on_success,\ - $(INFER_BIN) --results-dir $(@D) --check-duplicate-symbols \ + $(INFER_BIN) --results-dir $(@D) --dump-duplicate-symbols \ $(INFER_OPTIONS) -a $(ANALYZER) -- \ - clang $(CLANG_OPTIONS) $(SOURCES) 2> \ - >(tee duplicates.txt)) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + clang $(CLANG_OPTIONS) $(SOURCES)) + grep "DUPLICATE_SYMBOLS" infer-out$(TEST_SUFFIX)/duplicates.txt; test $$? -ne 0 diff --git a/infer/tests/codetoanalyze/cpp/checkers/siof/siof_templated.cpp b/infer/tests/codetoanalyze/cpp/checkers/siof/siof_templated.cpp index 264b5c882..bcbafb7f3 100644 --- a/infer/tests/codetoanalyze/cpp/checkers/siof/siof_templated.cpp +++ b/infer/tests/codetoanalyze/cpp/checkers/siof/siof_templated.cpp @@ -11,17 +11,17 @@ extern SomeTemplatedNonPODObject extern_global_object; -SomeTemplatedNonPODObject global_object; +SomeTemplatedNonPODObject global_template_object; template struct 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 }; SomeOtherTemplatedNonPODObject(int i) { - global_object.some_method(); // OK, same translation unit + global_template_object.some_method(); // OK, same translation unit }; }; diff --git a/infer/tests/codetoanalyze/objc/errors/Makefile b/infer/tests/codetoanalyze/objc/errors/Makefile index d4b819a56..4e9f7d982 100644 --- a/infer/tests/codetoanalyze/objc/errors/Makefile +++ b/infer/tests/codetoanalyze/objc/errors/Makefile @@ -18,7 +18,7 @@ CLANG_OPTIONS = -x objective-c \ 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 -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 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) $(call silent_on_success,\ $(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets all -o infer-out-all -- \ - clang $(CLANG_OPTIONS) $(SOURCES_BUCKET_ALL) 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + clang $(CLANG_OPTIONS) $(SOURCES_BUCKET_ALL)) + grep "DUPLICATE_SYMBOLS" infer-out-all/duplicates.txt; test $$? -ne 0 infer-out-arc/report.json: $(CLANG_DEPS) $(SOURCES_ARC) $(call silent_on_success,\ $(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets cf -o infer-out-arc -- \ - clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC) 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC)) + grep "DUPLICATE_SYMBOLS" infer-out-arc/duplicates.txt; test $$? -ne 0 infer-out/report.json: $(CLANG_DEPS) $(SOURCES_DEFAULT) $(call silent_on_success,\ $(INFER_BIN) -a $(ANALYZER) $(INFER_OPTIONS) --ml-buckets cf -o infer-out -- \ - clang $(CLANG_OPTIONS) $(SOURCES_DEFAULT) 2>duplicates.txt) - grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + clang $(CLANG_OPTIONS) $(SOURCES_DEFAULT)) + 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 $(INFERPRINT_BIN) -q -a $(ANALYZER) $(INFERPRINT_OPTIONS) $@.all \