Valgrind memcheck and TSAN script now uses Chrome+WebRTC suppression files.

Skeleton suppression files for future WebRTC suppressions are added and are included in addition to the ones Chrome are using and maintaining when our wrapper script executes.

Also added tweaked PRESUBMIT checks based on the Chrome code, that verifies
that suppressions are added correctly. I tested that they work by adding an invalid
suppression.

BUG=544
TEST=Tested running tools/valgrind-webrtc/webrtc_tests.sh --tool=tsan -t out/Debug/system_wrappers_unittests and it reports far less errors. Tested adding bad suppression and it was caught by the PRESUBMIT check.

Review URL: https://webrtc-codereview.appspot.com/601004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2304 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
kjellander@webrtc.org 2012-05-27 20:59:35 +00:00
parent 0d321da7e1
commit b6e4cc776e
11 changed files with 263 additions and 351 deletions

View File

@ -0,0 +1 @@
*

View File

@ -0,0 +1,99 @@
#!/usr/bin/env python
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
"""
Copied from Chrome's src/tools/valgrind/memcheck/PRESUBMIT.py
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details on the presubmit API built into gcl.
"""
import os
import re
import sys
def CheckChange(input_api, output_api):
"""Checks the memcheck suppressions files for bad data."""
# Add the path to the Chrome valgrind dir to the import path:
tools_vg_path = os.path.join(input_api.PresubmitLocalPath(), '..', '..',
'valgrind')
sys.path.append(tools_vg_path)
import suppressions
sup_regex = re.compile('suppressions.*\.txt$')
suppressions = {}
errors = []
check_for_memcheck = False
# skip_next_line has 3 possible values:
# - False: don't skip the next line.
# - 'skip_suppression_name': the next line is a suppression name, skip.
# - 'skip_param': the next line is a system call parameter error, skip.
skip_next_line = False
for f in filter(lambda x: sup_regex.search(x.LocalPath()),
input_api.AffectedFiles()):
for line, line_num in zip(f.NewContents(),
xrange(1, len(f.NewContents()) + 1)):
line = line.lstrip()
if line.startswith('#') or not line:
continue
if skip_next_line:
if skip_next_line == 'skip_suppression_name':
if 'insert_a_suppression_name_here' in line:
errors.append('"insert_a_suppression_name_here" is not a valid '
'suppression name')
if suppressions.has_key(line):
if f.LocalPath() == suppressions[line][1]:
errors.append('suppression with name "%s" at %s line %s '
'has already been defined at line %s' %
(line, f.LocalPath(), line_num,
suppressions[line][1]))
else:
errors.append('suppression with name "%s" at %s line %s '
'has already been defined at %s line %s' %
(line, f.LocalPath(), line_num,
suppressions[line][0], suppressions[line][1]))
else:
suppressions[line] = (f, line_num)
check_for_memcheck = True;
skip_next_line = False
continue
if check_for_memcheck:
if not line.startswith('Memcheck:'):
errors.append('"%s" should be "Memcheck:..." in %s line %s' %
(line, f.LocalPath(), line_num))
check_for_memcheck = False;
if line == '{':
skip_next_line = 'skip_suppression_name'
continue
if line == "Memcheck:Param":
skip_next_line = 'skip_param'
continue
if (line.startswith('fun:') or line.startswith('obj:') or
line.startswith('Memcheck:') or line == '}' or
line == '...'):
continue
errors.append('"%s" is probably wrong: %s line %s' % (line, f.LocalPath(),
line_num))
if errors:
return [output_api.PresubmitError('\n'.join(errors))]
return []
def CheckChangeOnUpload(input_api, output_api):
return CheckChange(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return CheckChange(input_api, output_api)
def GetPreferredTrySlaves():
# We don't have any memcheck slaves yet, so there's no use for this method.
# When we have, the slave name(s) should be put into this list.
return []

View File

@ -1,30 +1,11 @@
# There are four kinds of suppressions in this file.
# 1. third party stuff we have no control over
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# 2. intentional unit test errors, or stuff that is somehow a false positive
# in our own code, or stuff that is so trivial it's not worth fixing
#
# 3. Suppressions for real WebRTC bugs that are not yet fixed.
# These should all be in WebRTC's bug tracking system.
# Periodically we should sweep this file and the bug tracker clean by
# running overnight and removing outdated bugs/suppressions.
#
# 4. issues that happen only on Google workstations.
#-----------------------------------------------------------------------
# 1. third party stuff we have no control over
#-----------------------------------------------------------------------
# 2. intentional unit test errors, or stuff that is somehow a false positive
# in our own code, or stuff that is so trivial it's not worth fixing
#-----------------------------------------------------------------------
# 3. Suppressions for real chromium bugs that are not yet fixed.
# These should all be in WebRTC's bug tracking system.
#-----------------------------------------------------------------------
# 4. These only occur on our Google workstations
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# This file is used in addition to the one already maintained in Chrome.
# It acts as a place holder for future additions for WebRTC.
# It must exist for the Python wrapper script to work properly.

View File

@ -1,323 +1,11 @@
# There are three kinds of suppressions in this file:
# 1. Third party stuff we have no control over.
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# 2. Intentional unit test errors, stuff that is somehow a false positive
# in our own code, or stuff that is so trivial it's not worth fixing.
#
# 3. Suppressions for real WebRTC bugs that are not yet fixed.
# These should all be in WebRTC's bug tracking system.
# Periodically we should sweep this file and the bug tracker clean by
# running overnight and removing outdated bugs/suppressions.
#-----------------------------------------------------------------------
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# 1. Third party stuff we have no control over.
{
FIXME mac kevent libevent probably needs valgrind hooks
Memcheck:Param
kevent(changelist)
fun:kevent
fun:event_base_new
}
{
# CoreAudio leak. See http://crbug.com/9351
bug_9351
Memcheck:Leak
...
fun:_ZN12HALCADClient19AddPropertyListenerEmPK26AudioObjectPropertyAddressPFlmmS2_PvES3_
fun:_ZN16HALDefaultDevice22InstallServerListenersEv
fun:_ZN16HALDefaultDevice10InitializeEv
fun:_ZN9HALSystem16CheckOutInstanceEv
}
{
# Mac test_shell_tests. See http://crbug.com/11134
# Doesn't happen on bots, but happens like crazy on the smo
# test machine 'caliban'. Don't delete just because it
# doesn't happen on the bots.
bug_11134
Memcheck:Uninitialized
fun:vCMMVectorConvert8BitRGBToRGB
fun:_ZNK15CMMConvRGBToRGB7ConvertER8CMM8BitsP14CMMRuntimeInfomm
}
{
# Mac system library bug? See http://crbug.com/11327
bug_11327
Memcheck:Uninitialized
fun:_ZN19AudioConverterChain5ResetEv
fun:AudioConverterReset
obj:/System/Library/Components/CoreAudio.component/Contents/MacOS/CoreAudio
}
{
# Mac system library bug? See http://crbug.com/11327
bug_11327b
Memcheck:Uninitialized
fun:AUNetSendEntry
fun:AUNetSendEntry
obj:/System/Library/Components/CoreAudio.component/Contents/MacOS/CoreAudio
}
{
# Filed with Apple as rdar://6915060; see http://crbug.com/11270
bug_11270
Memcheck:Leak
fun:calloc
fun:CMSSetLabCLUT
}
{
# Mac leak in CMOpenOrNewAccess in unit_tests PlatformCanvas_SkLayer_Test,
# ToolbarControllerTest_FocusLocation_Test. See http://crbug.com/11333.
bug_11333
Memcheck:Leak
fun:malloc
fun:stdSmartNewPtr
fun:stdSmartNewHandle
fun:IOCreateAndOpen
fun:ScratchInit
fun:CMOpenOrNewAccess
}
{
# suddenly very common as of 6 aug 2009
bug_11333b
Memcheck:Leak
fun:malloc
fun:stdSmartNewPtr
fun:stdSmartNewHandle
fun:IOCreateAndOpen
fun:ScratchInit
fun:CMNewAccessFromAnother
}
{
# Tiny one-time leak, widely seen by valgind users; everyone suppresses this.
# See related discussion at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39366
plugin_bundle_global_leak
Memcheck:Leak
fun:malloc
fun:__cxa_get_globals
fun:__cxa_allocate_exception
fun:_ZN4dyld4loadEPKcRKNS_11LoadContextE
fun:dlopen
fun:dlopen
fun:_CFBundleDlfcnCheckLoaded
}
{
bug_18215
Memcheck:Uninitialized
fun:_DPSNextEvent
fun:-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
fun:-[NSApplication run]
}
{
bug_18223
Memcheck:Uninitialized
fun:_ZNK8Security12UnixPlusPlus17StaticForkMonitorclEv
fun:_ZN12ocspdGlobals10serverPortEv
}
{
# Filed with Apple as rdar://7255382
bug_20459a
Memcheck:Leak
...
fun:_CFRuntimeCreateInstance
fun:CFRunLoopSourceCreate
fun:CFMachPortCreateRunLoopSource
fun:_ZN8Security12MachPlusPlus10CFAutoPort6enableEv
fun:_ZN8Security14SecurityServer14ThreadNotifierC2Ev
}
{
# Also filed with Apple as rdar://7255382
bug_20459b
Memcheck:Leak
fun:malloc_zone_malloc
fun:_CFRuntimeCreateInstance
fun:__CFArrayInit
fun:CFArrayCreateMutableCopy
fun:_ZN8Security12KeychainCore5Trust8evaluateEv
}
# See description of bug_20653a/b in suppressions.txt.
{
bug_20653a_mac
Memcheck:Param
write(buf)
fun:write$UNIX2003
fun:pager_write_pagelist
}
{
bug_20653b_mac
Memcheck:Param
write(buf)
fun:write$UNIX2003
...
fun:pager_write
}
# See http://www.openradar.me/8287193
{
Invalid redzone accesses in DKeyHas8Words
Memcheck:Unaddressable
fun:DKeyHas8Words
}
# See https://bugs.kde.org/show_bug.cgi?id=188572
# This suppression is missing in Valgrind on Mac 10.6
# TODO(glider): remove it once it arrives in the trunk.
{
Unavoidable leak in setenv()
Memcheck:Leak
fun:malloc_zone_malloc
fun:__setenv
fun:setenv$UNIX2003
}
{
# Reported to Apple as rdar://6915429
bug_12525
Memcheck:Leak
...
fun:-[CIContextImpl render:toBitmap:rowBytes:bounds:format:colorSpace:]
}
{
bug_69436
Memcheck:Leak
...
fun:-[CIKernel initWithCString:noCopy:]
...
fun:-[NSPopUpButtonCell _drawIndicatorWithFrame:inView:]
}
{
# Capturer on Mac uses OpenGL driver, which triggers several warnings.
# The check has to be quite generic, as different hardware graphics cards
# will cause different sets of warnings.
bug_75037
Memcheck:Uninitialized
...
fun:_ZN8remoting*CapturerMac*
}
{
# See also http://openradar.appspot.com/radar?id=1235407
bug_77063
Memcheck:Free
fun:_ZdlPv
fun:_ZN15THFSPlusCatalogD2Ev
fun:_ZN5TNode10SetCatalogEP15THFSPlusCatalog
fun:_ZN15TMountPointList9AddVolumeEsb
fun:_ZN15TMountPointList4FindEsPN5TNode12StPopulatingE
fun:_ZN15TMountPointList20SupportsInvisibleBitEsPN5TNode12StPopulatingEb
fun:_ZNK21THFSPlusPropertyStore4OpenEbb
fun:_ZNK21THFSPlusPropertyStore13GetPropertiesEb
fun:_ZN16TFSCopyOperation22GetSourcePropertyStoreERK11THFSPlusRef
fun:_ZN16TFSCopyOperation13DoMoveToTrashERK11THFSPlusRef
fun:_ZN16TFSCopyOperation3RunEv
fun:_FSOperation
fun:_FSOperateOnObjectSync
fun:FSMoveObjectToTrashSync
fun:_Z9TrashFuncRK8FilePath
}
{
# See also http://openradar.appspot.com/radar?id=1169404
bug_79533a
Memcheck:Uninitialized
...
fun:_Z*19cssm_DataAbortQuery17cssm_dl_db_handlel
fun:CSSM_DL_DataAbortQuery
fun:_ZN11SSDLSession14DataAbortQueryEll
fun:_Z*19cssm_DataAbortQuery17cssm_dl_db_handlel
fun:CSSM_DL_DataAbortQuery
fun:tpDbFindIssuerCrl
fun:tpVerifyCertGroupWithCrls
}
{
# See also http://openradar.appspot.com/radar?id=1169404
bug_79533b
Memcheck:Uninitialized
...
fun:_Z*19cssm_DataAbortQuery17cssm_dl_db_handlel
fun:CSSM_DL_DataAbortQuery
fun:_ZN11SSDLSession14DataAbortQueryEll
fun:_Z*19cssm_DataAbortQuery17cssm_dl_db_handlel
fun:CSSM_DL_DataAbortQuery
fun:tpDbFindIssuerCrl
fun:tpVerifyCertGroupWithCrls
}
{
bug_85213_a
Memcheck:Leak
...
fun:_CFBundleCopyDirectoryContentsAtPath
}
{
bug_85213_b
Memcheck:Leak
...
fun:_CFBundleCopyInfoDictionaryInDirectoryWithVersion
}
{
bug_85213_c
Memcheck:Leak
...
fun:_CFBundleURLLooksLikeBundleVersion
}
{
bug_85213_d
Memcheck:Leak
...
fun:_CFBundleCreate
fun:_ZN6webkit5npapi9PluginLib17ReadWebPluginInfoERK8FilePathPNS0_13WebPluginInfoE
}
{
bug_85213_e
Memcheck:Leak
...
fun:CFBundlePreflightExecutable
fun:_ZN6webkit5npapi9PluginLib17ReadWebPluginInfoERK8FilePathPNS0_13WebPluginInfoE
}
{
bug_85213_f
Memcheck:Leak
...
fun:CFBundleGetPackageInfo
fun:_ZN6webkit5npapi9PluginLib17ReadWebPluginInfoERK8FilePathPNS0_13WebPluginInfoE
}
{
bug_86927
Memcheck:Leak
fun:malloc
fun:CGSMapShmem
fun:CGSResolveShmemReference
fun:CGSScoreboard
fun:initCGDisplayState
fun:initCGDisplayMappings
fun:cgsInit
fun:pthread_once
fun:CGSInitialize
fun:CGSServerOperationState
fun:+[NSThemeFrame initialize]
fun:_class_initialize
}
{
# QTKit leak. See http://crbug.com/100772 and rdar://10319535.
bug_100772
Memcheck:Leak
fun:calloc
fun:QTMLCreateMutex
fun:WarholCreateGlobals
fun:INIT_QuickTimeLibInternal
fun:pthread_once
fun:INIT_QuickTimeLib
fun:EnterMovies_priv
fun:EnterMovies
fun:TundraUnitInputFromTSFileEntry
fun:TundraUnitVDIGInputEntry
fun:TundraUnitCreateFromDescription
fun:+[QTCaptureVDIGDevice _refreshDevices]
fun:+[QTCaptureVDIGDevice devicesWithIOType:]
fun:+[QTCaptureDevice devicesWithIOType:]
fun:+[QTCaptureDevice inputDevices]
fun:+[QTCaptureDevice inputDevicesWithMediaType:]
fun:+[VideoCaptureDeviceQTKit deviceNames]
fun:_ZN5media18VideoCaptureDevice14GetDeviceNamesEPSt4listINS0_4NameESaIS2_EE
fun:_ZN5media21VideoCaptureDeviceMac4InitEv
fun:_ZN5media18VideoCaptureDevice6CreateERKNS0_4NameE
fun:_ZN5media45VideoCaptureDeviceTest_OpenInvalidDevice_Test8TestBodyEv
}
# 2. Intentional unit test errors, stuff that is somehow a false positive
# in our own code, or stuff that is so trivial it's not worth fixing.
# 3. Suppressions for real WebRTC bugs that are not yet fixed.
# This file is used in addition to the one already maintained in Chrome.
# It acts as a place holder for future additions for WebRTC.
# It must exist for the Python wrapper script to work properly.

View File

@ -0,0 +1,11 @@
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# This file is used in addition to the one already maintained in Chrome.
# It acts as a place holder for future additions for WebRTC.
# It must exist for the Python wrapper script to work properly.

View File

@ -0,0 +1 @@
*

View File

@ -0,0 +1,41 @@
#!/usr/bin/env python
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
import os
import re
import sys
"""
Copied from Chrome's src/tools/valgrind/tsan/PRESUBMIT.py
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details on the presubmit API built into gcl.
"""
def CheckChange(input_api, output_api):
"""Checks the TSan suppressions files for bad suppressions."""
# Add the path to the Chrome valgrind dir to the import path:
tools_vg_path = os.path.join(input_api.PresubmitLocalPath(), '..', '..',
'valgrind')
sys.path.append(tools_vg_path)
import suppressions
return suppressions.PresubmitCheck(input_api, output_api)
def CheckChangeOnUpload(input_api, output_api):
return CheckChange(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return CheckChange(input_api, output_api)
def GetPreferredTrySlaves():
# We don't have any tsan slaves yet, so there's no use for this method.
# When we have, the slave name(s) should be put into this list.
return []

View File

@ -0,0 +1,11 @@
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# This file is used in addition to the one already maintained in Chrome.
# It acts as a place holder for future additions for WebRTC.
# It must exist for the Python wrapper script to work properly.

View File

@ -0,0 +1,11 @@
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# This file is used in addition to the one already maintained in Chrome.
# It acts as a place holder for future additions for WebRTC.
# It must exist for the Python wrapper script to work properly.

View File

@ -0,0 +1,11 @@
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# This file is used in addition to the one already maintained in Chrome.
# It acts as a place holder for future additions for WebRTC.
# It must exist for the Python wrapper script to work properly.

View File

@ -15,15 +15,72 @@ we effectively can pass in any binary we feel like. It's also possible to pass
arguments to the test, provided that the arguments do not contain dashes (these
can be "escaped" by passing + instead, so -a becomes +a, and --my-option becomes
++my_option).
Suppression files:
The Chrome valgrind directory we use as a DEPS dependency contains the following
suppression files:
valgrind/memcheck/suppressions.txt
valgrind/memcheck/suppressions_mac.txt
valgrind/tsan/suppressions.txt
valgrind/tsan/suppressions_mac.txt
valgrind/tsan/suppressions_win32.txt
Since they're referenced from the chrome_tests.py script, we have similar files
below the directory of this script. When executing, this script will setup both
Chrome's suppression files and our own, so we can easily maintain WebRTC
specific suppressions in our own files.
'''
import optparse
import os
import sys
import logging_utils
import path_utils
import chrome_tests
class WebRTCTests(chrome_tests.ChromeTests):
"""Class that handles setup of suppressions for WebRTC.
Everything else is inherited from chrome_tests.ChromeTests.
"""
def _DefaultCommand(self, tool, exe=None, valgrind_test_args=None):
"""Override command-building method so we can add more suppressions."""
cmd = chrome_tests.ChromeTests._DefaultCommand(self, tool, exe,
valgrind_test_args)
# When ChromeTests._DefaultCommand has executed, it has setup suppression
# files based on what's found in the memcheck/ or tsan/ subdirectories of
# this script's location. If Mac or Windows is executing, additional
# platform specific files have also been added.
# Since only the ones located below this directory is added, we must also
# add the ones maintained by Chrome, located in ../valgrind.
# The idea is to look for --suppression arguments in the cmd list and add a
# modified copy of each suppression file, for the corresponding file in
# ../valgrind. If we would simply replace 'valgrind-webrtc' with 'valgrind'
# we may produce invalid paths if other parts of the path contain that
# string. That's why the code below only replaces the end of the path.
old_base, old_dir = _split_script_path()
new_dir = old_base + 'valgrind'
add_suppressions = []
for token in cmd:
if '--suppressions' in token:
add_suppressions.append(token.replace(old_base + old_dir, new_dir))
return add_suppressions + cmd
def _split_script_path():
"""Splits the script's path into a tuple separating the last directory.
Returns a tuple where the first item is the whole path except the last
directory and the second item is the name of the last directory.
"""
script_dir = path_utils.ScriptDir()
last_sep_index = script_dir.rfind(os.sep)
return script_dir[0:last_sep_index+1], script_dir[last_sep_index+1:]
def _main(_):
parser = optparse.OptionParser("usage: %prog -b <dir> -t <test> "
"[-t <test> ...] <arguments to all tests>"
@ -68,7 +125,7 @@ def _main(_):
translated_args = map(lambda arg: arg.replace('+', '-'), args)
for t in options.test:
tests = chrome_tests.ChromeTests(options, translated_args, t)
tests = WebRTCTests(options, translated_args, t)
ret = tests.Run()
if ret: return ret
return 0