From patchwork Wed Nov 14 22:59:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 199096 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D669C2C007E for ; Thu, 15 Nov 2012 12:28:09 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1353547690; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To: References:MIME-Version:Content-Type:Content-Disposition: Content-Transfer-Encoding:In-Reply-To:User-Agent:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=vWncwMRsQbNAmvifkfFqxmTTizM=; b=AAkY3/j6b4+OzXbNdUAQoVKni5PlSj1KktpwI9/KFZTyGW10ymhmbnvbPV27vZ +hu6GanDVNuIE4jsjS7UmESEmxYADvSZD7NXeKHI22bCGHb7gGsYzsPwPCpWGbkm aiIGQktzRmruZXCqym2SzHKy/z8Rrwo9QrJwf8xLxDRsA= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:References:MIME-Version:Content-Type:Content-Disposition:Content-Transfer-Encoding:In-Reply-To:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=gzPDRGkEDs1HViGB3N78EtA05ezmhWNePz0p9Fnq/c51uHdL/P92YDqPlGRKsS IzO2zqiNEUexBhzMd14MhxXKyqosn56+0P2q5Y7CMBCH2iTMQb+gQXye1r+2Y1B6 f41A6aymAV0ApsyR0E3HKIhV1E8pLGZMHtumpN7srdje4=; Received: (qmail 32153 invoked by alias); 15 Nov 2012 01:28:05 -0000 Received: (qmail 32145 invoked by uid 22791); 15 Nov 2012 01:28:05 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS, TW_FN X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 15 Nov 2012 01:27:58 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qAF1ROWC008687 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 14 Nov 2012 20:27:53 -0500 Received: from zalov.redhat.com (vpn1-4-119.ams2.redhat.com [10.36.4.119]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qAEMxDTj013853 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 14 Nov 2012 17:59:15 -0500 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.redhat.com (8.14.5/8.14.5) with ESMTP id qAEMxDh6027964; Wed, 14 Nov 2012 23:59:13 +0100 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id qAEMxC5Z027963; Wed, 14 Nov 2012 23:59:12 +0100 Date: Wed, 14 Nov 2012 23:59:12 +0100 From: Jakub Jelinek To: Mike Stump Cc: Wei Mi , Reiner Orth , Kostya Serebryany , GCC Patches Subject: Re: [PATCH] asan testsuite (take 3) Message-ID: <20121114225912.GM1886@tucnak.redhat.com> Reply-To: Jakub Jelinek References: <20121109144642.GD1886@tucnak.redhat.com> <20121114095202.GC1886@tucnak.redhat.com> <20121114111112.GD1886@tucnak.redhat.com> <20121114162215.GH1886@tucnak.redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On Wed, Nov 14, 2012 at 11:12:05AM -0800, Mike Stump wrote: > On Nov 14, 2012, at 8:22 AM, Jakub Jelinek wrote: > > On Wed, Nov 14, 2012 at 12:11:13PM +0100, Jakub Jelinek wrote: > >> Anyway, once asan_symbolize actually symbolizes the output, we could use > >> something like: > >> /* { dg-output "ERROR: AddressSanitizer stack-buffer-overflow.*" } */ > >> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)memcmp |\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > >> (this way it will check function names if symbolizer was actually > >> successful, and just accept #0 0xdeadbeef (foobarbaz.so+0xbeef) style > >> if it wasn't), but will not accept other function names in the backtrace. > > > > Here it is even with symbolizer, written in (poor) tcl. It will pass even > > if e.g. addr2line is replaced by a script that always fails, but if it > > succeeds, will fail if the dg-output regexps contain different function name > > than what is actually emitted. > > > > Ok for trunk? > > Ok. If others would like to improve this… :-) feel free to step forward. Thanks, here is what I've committed, had to add a TEST_ALWAYS_FLAG restore in asan_finish, otherwise C tests after asan.exp would run with -faddress-sanitizer -g in the flags. 2012-11-14 Jakub Jelinek * lib/asan-dg.exp: New file. * gcc.dg/asan/asan.exp: New file. * g++.dg/dg.exp: Prune also asan tests. * g++.dg/asan/asan.exp: New file. * c-c++-common/asan/memcmp-1.c: New test. Jakub --- gcc/testsuite/lib/asan-dg.exp.jj 2012-11-14 21:04:53.520943144 +0100 +++ gcc/testsuite/lib/asan-dg.exp 2012-11-14 21:21:03.215801626 +0100 @@ -0,0 +1,176 @@ +# Copyright (C) 2012 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Return 1 if compilation with -faddress-sanitizer is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_faddress_sanitizer {} { + return [check_no_compiler_messages faddress_sanitizer object { + void foo (void) { } + } "-faddress-sanitizer"] +} + +# +# asan_link_flags -- compute library path and flags to find libasan. +# (originally from g++.exp) +# + +proc asan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"] + || [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } { + append flags " -L${gccpath}/libsanitizer/asan/.libs " + append ld_library_path ":${gccpath}/libsanitizer/asan/.libs" + } + } else { + global tool_root_dir + + set libasan [lookfor_file ${tool_root_dir} libasan] + if { $libasan != "" } { + append flags "-L${libasan} " + append ld_library_path ":${libasan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# asan_init -- called at the start of each subdir of tests +# + +proc asan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global asan_saved_TEST_ALWAYS_FLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[asan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[asan_link_flags [get_multilibs]]" + } + } + + if [info exists TEST_ALWAYS_FLAGS] { + set asan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + set ALWAYS_CXXFLAGS [concat "{additional_flags=-faddress-sanitizer -g}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags -faddress-sanitizer -g $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags -faddress-sanitizer -g" + } + } +} + +# +# asan_finish -- called at the start of each subdir of tests +# + +proc asan_finish { args } { + global TEST_ALWAYS_FLAGS + global asan_saved_TEST_ALWAYS_FLAGS + + if [info exists asan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $asan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } +} + +# Symbolize lines like +# #2 0xdeadbeef (/some/path/libsanitizer.so.0.0.0+0xbeef) +# in $output using addr2line to +# #2 0xdeadbeef in foobar file:123 +proc asan_symbolize { output } { + set addresses [regexp -inline -all -line "^ *#\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+)\[+\](0x\[0-9a-f\]+)\[)\]$" "$output"] + if { [llength $addresses] > 0 } { + set addr2line_name [find_binutils_prog addr2line] + set idx 1 + while { $idx < [llength $addresses] } { + set key [lindex $addresses $idx] + set val [lindex $addresses [expr $idx + 1]] + lappend arr($key) $val + set idx [expr $idx + 3] + } + foreach key [array names arr] { + set args "-f -e $key $arr($key)" + set status [remote_exec host "$addr2line_name" $args] + if { [lindex $status 0] > 0 } continue + set addr2line_output [regexp -inline -all -line "^\[^\n\r]*" [lindex $status 1]] + set idx 0 + foreach val $arr($key) { + if { [expr $idx + 1] < [llength $addr2line_output] } { + set fnname [lindex $addr2line_output $idx] + set fileline [lindex $addr2line_output [expr $idx + 1]] + if { "$fnname" != "??" } { + set newkey "$key+$val" + set repl($newkey) "$fnname $fileline" + } + } + } + } + set idx 0 + set new_output "" + while {[regexp -start $idx -indices " #\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+\[+\]0x\[0-9a-f\]+)\[)\]" "$output" -> addr] > 0} { + set low [lindex $addr 0] + set high [lindex $addr 1] + set val [string range "$output" $low $high] + append new_output [string range "$output" $idx [expr $low - 2]] + if [info exists repl($val)] { + append new_output "in $repl($val)" + } else { + append new_output "($val)" + } + set idx [expr $high + 2] + } + append new_output [string range "$output" $idx [string length "$output"]] + return "$new_output" + } + return "$output" +} + +# Replace ${tool}_load with a wrapper so that we can symbolize the output. +if { [info procs ${tool}_load] != [list] \ + && [info procs saved_asan_${tool}_load] == [list] } { + rename ${tool}_load saved_asan_${tool}_load + + proc ${tool}_load { program args } { + global tool + set result [eval [list saved_asan_${tool}_load $program] $args] + set output [lindex $result 1] + set symbolized_output [asan_symbolize "$output"] + set result [list [lindex $result 0] $symbolized_output] + return $result + } +} --- gcc/testsuite/gcc.dg/asan/asan.exp.jj 2012-11-14 21:04:53.520943144 +0100 +++ gcc/testsuite/gcc.dg/asan/asan.exp 2012-11-14 21:07:25.213157962 +0100 @@ -0,0 +1,38 @@ +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp +load_lib asan-dg.exp + +if ![check_effective_target_faddress_sanitizer] { + return +} + +# Initialize `dg'. +dg-init +asan_init + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/asan/*.c]] "" + +# All done. +asan_finish +dg-finish --- gcc/testsuite/g++.dg/dg.exp.jj 2012-11-14 20:26:35.460378708 +0100 +++ gcc/testsuite/g++.dg/dg.exp 2012-11-14 21:04:53.520943144 +0100 @@ -1,4 +1,5 @@ -# Copyright (C) 2000, 2007, 2009, 2010 Free Software Foundation, Inc. +# Copyright (C) 2000, 2007, 2009, 2010, 2011, 2012 +# Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -50,6 +51,7 @@ set tests [prune $tests $srcdir/$subdir/ set tests [prune $tests $srcdir/$subdir/tm/*] set tests [prune $tests $srcdir/$subdir/guality/*] set tests [prune $tests $srcdir/$subdir/simulate-thread/*] +set tests [prune $tests $srcdir/$subdir/asan/*] # Main loop. g++-dg-runtest $tests $DEFAULT_CXXFLAGS --- gcc/testsuite/g++.dg/asan/asan.exp.jj 2012-11-14 21:04:53.520943144 +0100 +++ gcc/testsuite/g++.dg/asan/asan.exp 2012-11-14 21:07:35.967092385 +0100 @@ -0,0 +1,36 @@ +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Load support procs. +load_lib g++-dg.exp +load_lib asan-dg.exp + +if ![check_effective_target_faddress_sanitizer] { + return +} + +# Initialize `dg'. +dg-init +asan_init + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/asan/*.c]] "" + +# All done. +asan_finish +dg-finish --- gcc/testsuite/c-c++-common/asan/memcmp-1.c.jj 2012-11-14 21:04:53.521943120 +0100 +++ gcc/testsuite/c-c++-common/asan/memcmp-1.c 2012-11-14 21:04:53.521943120 +0100 @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-memcmp" } */ +/* { dg-shouldfail "asan" } */ + +#include + +int +main (int argc, char **argv) +{ + char a1[] = {argc, 2, 3, 4}; + char a2[] = {1, 2*argc, 3, 4}; + int res = memcmp (a1, a2, 5 + argc); + return res; +} + +/* { dg-output "ERROR: AddressSanitizer stack-buffer-overflow.*(\n|\r\n|\r)" } */ +/* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)memcmp |\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */