From: Reuben Thomas Date: Thu, 25 Jan 2018 09:52:41 +0000 (+0000) Subject: Run tests with valgrind X-Git-Tag: v3.7~50 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ae666693e4e36c5f802977cca84d13435f59120;p=recode Run tests with valgrind Use the valgrind-python.supp suppressions file (latest version from cpython git), adding wildcard * to end of PyObject_Realloc name to match LTO symbols. However, even this is not currently enough to run with the standard /usr/bin/python, so use /usr/bin/python-dbg instead, which does work (with some extra suppressions). See https://bugs.python.org/issue32666 Remove a bogus setting of PYTHON in tests/Makefile.am --- diff --git a/.gitignore b/.gitignore index 5b4cb5d..b784cf4 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ html/ /tests/Recode.body.c /tests/Recode.c /tests/Recode.so +/tests/Recode_d.so diff --git a/.travis.yml b/.travis.yml index 5e7c2c8..f5a1cc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,11 +8,12 @@ addons: sources: - ubuntu-toolchain-r-test packages: &default_deps - - python + - python-dbg - cython - flex - help2man - texinfo + - valgrind - g++-5 # env: @@ -39,7 +40,7 @@ matrix: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python cython flex help2man texinfo ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python cython flex help2man texinfo valgrind ; fi # Need gettext 0.19, not in trusty; xenial doesn’t seem to work well yet on Travis install: @@ -49,6 +50,6 @@ install: script: - ./bootstrap - - ./configure + - ./configure PYTHON=/usr/bin/python-dbg - make - - make distcheck + - make DISTCHECK_CONFIGURE_FLAGS="PYTHON=/usr/bin/python-dbg" distcheck diff --git a/bootstrap.conf b/bootstrap.conf index 639b067..84a7f2f 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,4 +1,4 @@ -# bootstrap.conf (Recode) version 2018-01-23 +# bootstrap.conf (Recode) version 2018-01-24 # This file is part of Recode. # @@ -68,6 +68,7 @@ gnulib_modules=' sys_wait unistd utime + valgrind-tests vasprintf vprintf-posix xalloc diff --git a/m4/.gitignore b/m4/.gitignore index b18525e..ea3690d 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -138,3 +138,4 @@ gnulib-comp.m4 /tempname.m4 /xstrndup.m4 /vasprintf.m4 +/valgrind-tests.m4 diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..29d3df3 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,6 @@ +/_Noreturn.h +/arg-nonnull.h +/c++defs.h +/dummy.c +/unused-parameter.h +/warn-on-use.h diff --git a/tests/Makefile.am b/tests/Makefile.am index a711083..9e8a285 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,16 +27,15 @@ SUITE = t21_names.py t22_lists.py t25_subsets.py t30_base64.py \ t30_dumps.py t30_quoted.py t40_african.py t40_combine.py t40_testdump.py \ t40_utf7.py t40_utf8.py t50_methods.py t90_bigauto.py -EXTRA_DIST = Recode.c Recode.pyx pytest common.py $(SUITE) -CLEANFILES = Recode@shlibext@ Recode.body.c +EXTRA_DIST = Recode.c Recode.pyx pytest common.py valgrind-python.supp $(SUITE) +CLEANFILES = Recode@shlibext@ Recode_d@shlibext@ Recode.body.c DISTCLEANFILES = Recode.c -PYTHON = python - check-local: Recode@shlibext@ - export LD_LIBRARY_PATH=$(top_builddir)/src/@objdir@ && \ + if test -n "$(VALGRIND)"; then export VALGRIND='$(VALGRIND) --suppressions=$(srcdir)/valgrind-python.supp'; fi; \ + export LD_LIBRARY_PATH=$(top_builddir)/src/@objdir@; \ RECODE=$(top_builddir)/src/recode PYTHONPATH=.:$(srcdir) \ - $(PYTHON) $(srcdir)/pytest $(LIMIT) $(srcdir)/t*.py + $$VALGRIND $(PYTHON) $(srcdir)/pytest $(LIMIT) $(srcdir)/t*.py Recode@shlibext@: Recode.c setup.py rm -f *@shlibext@ diff --git a/tests/valgrind-python.supp b/tests/valgrind-python.supp new file mode 100644 index 0000000..53cabca --- /dev/null +++ b/tests/valgrind-python.supp @@ -0,0 +1,496 @@ +# +# This is a valgrind suppression file that should be used when using valgrind. +# +# Here's an example of running valgrind: +# +# cd python/dist/src +# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \ +# ./python -E ./Lib/test/regrtest.py -u gui,network +# +# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER +# to use the preferred suppressions with Py_ADDRESS_IN_RANGE. +# +# If you do not want to recompile Python, you can uncomment +# suppressions for PyObject_Free and PyObject_Realloc. +# +# See Misc/README.valgrind for more information. + +# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64) + Memcheck:Value8 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:Py_ADDRESS_IN_RANGE +} + +# +# Leaks (including possible leaks) +# Hmmm, I wonder if this masks some real leaks. I think it does. +# Will need to fix that. +# + +{ + Suppress debugging leaks + Memcheck:Leak + fun:malloc + fun:PyObject_Malloc + fun:_PyObject_DebugMallocApi +} + +{ + Suppress debugging leaks + Memcheck:Leak + fun:realloc + fun:PyObject_Realloc + fun:_PyObject_DebugReallocApi +} + +{ + Suppress leaking the GIL. Happens once per process, see comment in ceval.c. + Memcheck:Leak + fun:malloc + fun:PyThread_allocate_lock + fun:PyEval_InitThreads +} + +{ + Suppress leaking the GIL after a fork. + Memcheck:Leak + fun:malloc + fun:PyThread_allocate_lock + fun:PyEval_ReInitThreads +} + +{ + Suppress leaking the autoTLSkey. This looks like it shouldn't leak though. + Memcheck:Leak + fun:malloc + fun:PyThread_create_key + fun:_PyGILState_Init + fun:Py_InitializeEx + fun:Py_Main +} + +{ + Hmmm, is this a real leak or like the GIL? + Memcheck:Leak + fun:malloc + fun:PyThread_ReInitTLS +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:realloc + fun:_PyObject_GC_Resize + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_New + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_NewVar + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +# +# Non-python specific leaks +# + +{ + Handle pthread issue (possibly leaked) + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls_storage + fun:_dl_allocate_tls +} + +{ + Handle pthread issue (possibly leaked) + Memcheck:Leak + fun:memalign + fun:_dl_allocate_tls_storage + fun:_dl_allocate_tls +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Use of uninitialised value of size 8 + Memcheck:Addr8 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Use of uninitialised value of size 8 + Memcheck:Value8 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:PyObject_Realloc* +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:PyObject_Realloc* +} + +{ + ADDRESS_IN_RANGE/Use of uninitialised value of size 8 + Memcheck:Addr8 + fun:PyObject_Realloc* +} + +{ + ADDRESS_IN_RANGE/Use of uninitialised value of size 8 + Memcheck:Value8 + fun:PyObject_Realloc* +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:PyObject_Realloc* +} + +### +### All the suppressions below are for errors that occur within libraries +### that Python uses. The problems to not appear to be related to Python's +### use of the libraries. +### + +{ + Generic ubuntu ld problems + Memcheck:Addr8 + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} + +{ + Generic gentoo ld problems + Memcheck:Cond + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so +} + +{ + DBM problems, see test_dbm + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_close +} + +{ + DBM problems, see test_dbm + Memcheck:Value8 + fun:memmove + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + DBM problems, see test_dbm + Memcheck:Cond + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + DBM problems, see test_dbm + Memcheck:Cond + fun:memmove + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + GDBM problems, see test_gdbm + Memcheck:Param + write(buf) + fun:write + fun:gdbm_open + +} + +{ + ZLIB problems, see test_gzip + Memcheck:Cond + obj:/lib/libz.so.1.2.3 + obj:/lib/libz.so.1.2.3 + fun:deflate +} + +{ + Avoid problems w/readline doing a putenv and leaking on exit + Memcheck:Leak + fun:malloc + fun:xmalloc + fun:sh_set_lines_and_columns + fun:_rl_get_screen_size + fun:_rl_init_terminal_io + obj:/lib/libreadline.so.4.3 + fun:rl_initialize +} + +### +### These occur from somewhere within the SSL, when running +### test_socket_sll. They are too general to leave on by default. +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:memset +###} +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:memset +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:MD5_Update +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:MD5_Update +###} + +# Fedora's package "openssl-1.0.1-0.1.beta2.fc17.x86_64" on x86_64 +# See http://bugs.python.org/issue14171 +{ + openssl 1.0.1 prng 1 + Memcheck:Cond + fun:bcmp + fun:fips_get_entropy + fun:FIPS_drbg_instantiate + fun:RAND_init_fips + fun:OPENSSL_init_library + fun:SSL_library_init + fun:init_hashlib +} + +{ + openssl 1.0.1 prng 2 + Memcheck:Cond + fun:fips_get_entropy + fun:FIPS_drbg_instantiate + fun:RAND_init_fips + fun:OPENSSL_init_library + fun:SSL_library_init + fun:init_hashlib +} + +{ + openssl 1.0.1 prng 3 + Memcheck:Value8 + fun:_x86_64_AES_encrypt_compact + fun:AES_encrypt +} + +# +# All of these problems come from using test_socket_ssl +# +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_bin2bn +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont +} + +{ + from test_socket_ssl + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libcrypto.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_set_key_unchecked +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_encrypt2 +} + +{ + from test_socket_ssl + Memcheck:Cond + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Value4 + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BUF_MEM_grow_clean +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:memcpy + fun:ssl3_read_bytes +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:SHA1_Update +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:SHA1_Update +} + +{ + test_buffer_non_debug + Memcheck:Addr4 + fun:PyUnicodeUCS2_FSConverter +} + +{ + test_buffer_non_debug + Memcheck:Addr4 + fun:PyUnicode_FSConverter +} + +{ + wcscmp_false_positive + Memcheck:Addr8 + fun:wcscmp + fun:_PyOS_GetOpt + fun:Py_Main + fun:main +} + +# Additional suppressions for the unified decimal tests: +{ + test_decimal + Memcheck:Addr4 + fun:PyUnicodeUCS2_FSConverter +} + +{ + test_decimal2 + Memcheck:Addr4 + fun:PyUnicode_FSConverter +} +