From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 95169 invoked by alias); 19 Nov 2015 14:38:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 95154 invoked by uid 89); 19 Nov 2015 14:38:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=3.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS,ZIP_ATTACHED autolearn=no version=3.3.2 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Thu, 19 Nov 2015 14:38:46 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 58904AC76 for ; Thu, 19 Nov 2015 14:38:18 +0000 (UTC) To: GCC Patches From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Subject: [PATCH,RFC] Introduce RUN_UNDER_VALGRIND in test-suite Message-ID: <564DDEF2.8090803@suse.cz> Date: Thu, 19 Nov 2015 14:38:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------000104070803060908090405" X-IsSubscribed: yes X-SW-Source: 2015-11/txt/msg02339.txt.bz2 This is a multi-part message in MIME format. --------------000104070803060908090405 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 2063 Hello. In last two weeks I've removed couple of memory leaks, mainly tight to middle-end. Currently, a user of the GCC compiler can pass '--enable-checking=valgrind' configure option that will run all commands within valgrind environment, but as the valgrind runs just with '-q' option, the result is not very helpful. I would like to start with another approach, where we can run all tests in test-suite within the valgrind sandbox and return an exit code if there's an error seen by the tool. That unfortunately leads to many latent (maybe false positives, FE issues, ...) that can be efficiently ignored by valgrind suppressions file (the file is part of suggested patch). The first version of the valgrind.supp can survive running compilation of tramp3d with -O2 and majority of tests in test-suite can successfully finish. Most of memory leaks mentioned in the file can be eventually fixed. As I noticed in results log files, most of remaining issues are connected to gcc.c and lto-wrapper.c files. gcc.c heavily manipulates with strings and it would probably require usage of a string pool, that can easily eventually removed (just in case of --enable-valgrind-annotations). The second source file tends to produce memory leaks because of fork/exec constructs. However both can be improved during next stage1. Apart from aforementioned issues, the compiler does not contain so many issues and I think it's doable to prune them and rely on reported valgrind errors. Patch touches many .exp files, but basically does just couple of modifications: 1) gcc-defs.exp introduces new global variable run_under_valgrind 2) new procedure dg-run-valgrind distinguishes between just passing options to 'gd-test', or runs 'dg-test' with additional flags that enable valgrind (using -wrapper) 3) new procedure dg-runtest-valgrind does the similar 4) many changes in corresponding *.exp files that utilize these procedures The patch should be definitely part of next stage1, but I would appreciate any thoughts about the described approach? Thank you, Martin --------------000104070803060908090405 Content-Type: text/x-patch; name="0001-Introduce-RUN_UNDER_VALGRIND-support-in-dg-test-proc.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Introduce-RUN_UNDER_VALGRIND-support-in-dg-test-proc.pa"; filename*1="tch" Content-length: 9153 >From 61286c72b747a1543fc08bad87566afb3656067c Mon Sep 17 00:00:00 2001 From: marxin Date: Wed, 18 Nov 2015 17:49:03 +0100 Subject: [PATCH 1/2] Introduce RUN_UNDER_VALGRIND support in dg-test procedure contrib/ChangeLog: 2015-11-19 Martin Liska * valgrind.supp: New file. gcc/testsuite/ChangeLog: 2015-11-19 Martin Liska * jit.dg/jit.exp: Use global run_under_valgrind instead of the local one. * lib/g++-dg.exp: Replace dg-test with dg-test-valgrind. * lib/gcc-defs.exp: Introduce global variable run_under_valgrind. * lib/gcc-dg.exp: Add -wrapper that runs a test in valgrind. * lib/gfortran-dg.exp: Replace dg-test with dg-test-valgrind. * lib/obj-c++-dg.exp: Replace dg-test with dg-test-valgrind. * lib/objc-dg.exp: Replace dg-test with dg-test-valgrind. --- contrib/valgrind.supp | 108 ++++++++++++++++++++++++++++++++++++++ gcc/testsuite/jit.dg/jit.exp | 2 +- gcc/testsuite/lib/g++-dg.exp | 2 +- gcc/testsuite/lib/gcc-defs.exp | 3 ++ gcc/testsuite/lib/gcc-dg.exp | 30 ++++++++++- gcc/testsuite/lib/gfortran-dg.exp | 4 +- gcc/testsuite/lib/obj-c++-dg.exp | 4 +- gcc/testsuite/lib/objc-dg.exp | 2 +- 8 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 contrib/valgrind.supp diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp new file mode 100644 index 0000000..deefb28 --- /dev/null +++ b/contrib/valgrind.supp @@ -0,0 +1,108 @@ +{ + cpp_get_buff + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:xmalloc + fun:new_buff + fun:_cpp_get_buff + ... +} +{ + gnu-as + Memcheck:Leak + match-leak-kinds: definite,possible + fun:malloc + ... + obj:/usr/bin/as + ... +} +{ + gnu-as + Memcheck:Leak + match-leak-kinds: definite,possible + fun:calloc + fun:xcalloc + ... + obj:/usr/bin/as + ... +} +{ + todo-fix-mpfr + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:__gmp_default_allocate + fun:mpfr_init2 + fun:mpfr_cache + fun:mpfr_log + ... +} +{ + cpp-front-end + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:xmalloc + fun:_ZL22cp_literal_operator_idPKc + fun:cp_parser_template_name + ... +} +{ + todo-fix-options1 + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:xcalloc + fun:_Z20lang_specific_driverPP17cl_decoded_optionPjPi + fun:_ZL15process_commandjP17cl_decoded_option + fun:_ZNK6driver12set_up_specsEv + fun:_ZN6driver4mainEiPPc + fun:main +} +{ + todo-fix-options2 + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:xmalloc + fun:_Z20lang_specific_driverPP17cl_decoded_optionPjPi + fun:_ZL15process_commandjP17cl_decoded_option + fun:_ZNK6driver12set_up_specsEv + fun:_ZN6driver4mainEiPPc + fun:main +} +{ + ld.bfd-alloc + Memcheck:Leak + match-leak-kinds: definite,possible + fun:malloc + ... + obj:/usr/bin/ld.bfd + ... +} +{ + ld.bfd-realloc + Memcheck:Leak + match-leak-kinds: definite,possible + fun:realloc + ... + obj:/usr/bin/ld.bfd + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:xcalloc + fun:main +} +{ + collect2 + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:xcalloc + fun:main +} diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp index 39e37c2..155a4cf 100644 --- a/gcc/testsuite/jit.dg/jit.exp +++ b/gcc/testsuite/jit.dg/jit.exp @@ -138,6 +138,7 @@ proc fixed_host_execute {args} { global env global text global spawn_id + global run_under_valgrind verbose "fixed_host_execute: $args" @@ -169,7 +170,6 @@ proc fixed_host_execute {args} { # Run under valgrind if RUN_UNDER_VALGRIND is present in the environment. # Note that it's best to configure gcc with --enable-valgrind-annotations # when testing under valgrind. - set run_under_valgrind [info exists env(RUN_UNDER_VALGRIND)] if $run_under_valgrind { set valgrind_logfile "${executable}.valgrind.txt" set valgrind_params {"valgrind"} diff --git a/gcc/testsuite/lib/g++-dg.exp b/gcc/testsuite/lib/g++-dg.exp index 421f8b6..7b2f89c 100644 --- a/gcc/testsuite/lib/g++-dg.exp +++ b/gcc/testsuite/lib/g++-dg.exp @@ -55,7 +55,7 @@ proc g++-dg-runtest { testcases flags default-extra-flags } { foreach flags_t $option_list { verbose "Testing $nshort, $flags $flags_t" 1 - dg-test $test "$flags $flags_t" ${default-extra-flags} + dg-test-valgrind $test "$flags $flags_t" ${default-extra-flags} } } } diff --git a/gcc/testsuite/lib/gcc-defs.exp b/gcc/testsuite/lib/gcc-defs.exp index a30b176..7d4a0c5 100644 --- a/gcc/testsuite/lib/gcc-defs.exp +++ b/gcc/testsuite/lib/gcc-defs.exp @@ -352,3 +352,6 @@ proc gcc-set-multilib-library-path { compiler } { return $libpath } + +global run_under_valgrind +set run_under_valgrind [info exists env(RUN_UNDER_VALGRIND)] diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index 8cc1d87..93a8db2 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -310,6 +310,19 @@ proc gcc-dg-test { prog do_what extra_tool_flags } { return [gcc-dg-test-1 gcc_target_compile $prog $do_what $extra_tool_flags] } +proc dg-test-valgrind { test flags default-extra-flags } { + global srcdir + global run_under_valgrind + + set valgrind_command "valgrind,--leak-check=yes,--trace-children=yes,--suppressions=${srcdir}/../../contrib/valgrind.supp,--error-exitcode=111,-q" + + if $run_under_valgrind { + dg-test $test "$flags -wrapper $valgrind_command" ${default-extra-flags} + } else { + dg-test $test $flags ${default-extra-flags} + } +} + proc gcc-dg-prune { system text } { global additional_prunes @@ -443,6 +456,19 @@ proc search_for { file pattern } { return 0 } +proc dg-runtest-valgrind { testcases flags default-extra-flags } { + global runtests + + foreach testcase $testcases { + # If we're only testing specific files and this isn't one of them, skip it. + if {![runtest_file_p $runtests $testcase]} { + continue + } + verbose "Testing [file tail [file dirname $testcase]]/[file tail $testcase]" + dg-test-valgrind $testcase $flags ${default-extra-flags} + } +} + # Modified dg-runtest that can cycle through a list of optimization options # as c-torture does. proc gcc-dg-runtest { testcases flags default-extra-flags } { @@ -477,7 +503,7 @@ proc gcc-dg-runtest { testcases flags default-extra-flags } { foreach flags_t $option_list { verbose "Testing $nshort, $flags $flags_t" 1 - dg-test $test "$flags $flags_t" ${default-extra-flags} + dg-test-valgrind $test "$flags $flags_t" ${default-extra-flags} } } @@ -556,7 +582,7 @@ proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } { if { $doit } { verbose -log "Testing $nshort, $flags" 1 - dg-test $test $flags "" + dg-test-valgrind $test $flags "" } } } diff --git a/gcc/testsuite/lib/gfortran-dg.exp b/gcc/testsuite/lib/gfortran-dg.exp index ddf8f22..075586c 100644 --- a/gcc/testsuite/lib/gfortran-dg.exp +++ b/gcc/testsuite/lib/gfortran-dg.exp @@ -134,7 +134,7 @@ proc gfortran-dg-runtest { testcases flags default-extra-flags } { foreach flags_t $option_list { verbose "Testing $nshort, $flags $flags_t" 1 - dg-test $test "$flags $flags_t" ${default-extra-flags} + dg-test-valgrind $test "$flags $flags_t" ${default-extra-flags} cleanup-modules "" } } @@ -200,7 +200,7 @@ proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } { if { $doit } { verbose -log "Testing $nshort, $flags" 1 - dg-test $test $flags "" + dg-test-valgrind $test $flags "" cleanup-modules "" } } diff --git a/gcc/testsuite/lib/obj-c++-dg.exp b/gcc/testsuite/lib/obj-c++-dg.exp index 7ba10f1..3a8dfb5 100644 --- a/gcc/testsuite/lib/obj-c++-dg.exp +++ b/gcc/testsuite/lib/obj-c++-dg.exp @@ -63,11 +63,11 @@ proc obj-c++-dg-runtest { testcases flags default-extra-flags } { # combine flags so that dg-skip & xfail will see the extras. set combined_flags "$flags $flags_t ${default-extra-flags}" verbose "Testing $nshort, $combined_flags" 1 - dg-test $test $combined_flags "" + dg-test-valgrind $test $combined_flags "" } } if { $existing_torture_options == 0 } { torture-finish } -} \ No newline at end of file +} diff --git a/gcc/testsuite/lib/objc-dg.exp b/gcc/testsuite/lib/objc-dg.exp index 5782593..9c1173f 100644 --- a/gcc/testsuite/lib/objc-dg.exp +++ b/gcc/testsuite/lib/objc-dg.exp @@ -64,7 +64,7 @@ proc objc-dg-runtest { testcases flags default-extra-flags } { # combine flags so that dg-skip & xfail will see the extras. set combined_flags "$flags $flags_t ${default-extra-flags}" verbose "Testing $nshort, $combined_flags" 1 - dg-test $test $combined_flags "" + dg-test-valgrind $test $combined_flags "" } } -- 2.6.3 --------------000104070803060908090405 Content-Type: application/x-bzip; name="0002-Replace-dg-runtest-with-dg-runtest-valgrind.patch.bz2" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename*0="0002-Replace-dg-runtest-with-dg-runtest-valgrind.patch.bz2" Content-length: 13071 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 8XckU4UJDx4CIYA= --------------000104070803060908090405--