Merge branch '487-ci-memcheck' into 'master'

Add CI job for running tests under Valgrind

Closes #487

See merge request GNOME/glib!169
This commit is contained in:
Sebastian Dröge 2019-09-02 13:52:35 +00:00
commit daa308dd6e
8 changed files with 142 additions and 18 deletions

View File

@ -14,7 +14,7 @@ variables:
MESON_COMMON_OPTIONS: "--buildtype debug --fatal-meson-warnings" MESON_COMMON_OPTIONS: "--buildtype debug --fatal-meson-warnings"
fedora-x86_64: fedora-x86_64:
image: registry.gitlab.gnome.org/gnome/glib/fedora:v2 image: registry.gitlab.gnome.org/gnome/glib/fedora:v3
stage: build stage: build
except: except:
- tags - tags
@ -84,7 +84,7 @@ debian-stable-x86_64:
- "_build/${CI_JOB_NAME}-report.xml" - "_build/${CI_JOB_NAME}-report.xml"
G_DISABLE_ASSERT: G_DISABLE_ASSERT:
image: registry.gitlab.gnome.org/gnome/glib/fedora:v2 image: registry.gitlab.gnome.org/gnome/glib/fedora:v3
stage: build stage: build
except: except:
- tags - tags
@ -111,6 +111,40 @@ G_DISABLE_ASSERT:
- "_build/meson-logs" - "_build/meson-logs"
- "_build/${CI_JOB_NAME}-report.xml" - "_build/${CI_JOB_NAME}-report.xml"
valgrind:
image: registry.gitlab.gnome.org/gnome/glib/fedora:v3
stage: analysis
except:
- tags
variables:
MESON_TEST_TIMEOUT_MULTIPLIER: 10
script:
- meson ${MESON_COMMON_OPTIONS}
--werror
-Dsystemtap=true
-Ddtrace=true
-Dfam=true
-Dinstalled_tests=true
_build
- ninja -C _build
- bash -x ./.gitlab-ci/run-tests.sh
--log-file _build/meson-logs/testlog-valgrind.json
--wrap "valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes --leak-check=full --leak-resolution=high --num-callers=50 --show-leak-kinds=definite,possible --show-error-list=yes --suppressions=${CI_PROJECT_DIR}/glib.supp"
--no-suite no-valgrind
--no-suite slow
# FIXME: Remove this when we have zero valgrind leaks.
# https://gitlab.gnome.org/GNOME/glib/issues/333
allow_failure: true
artifacts:
reports:
junit: "_build/${CI_JOB_NAME}-report.xml"
name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
when: always
paths:
- "_build/config.h"
- "_build/glib/glibconfig.h"
- "_build/meson-logs"
.cross-template: &cross-template .cross-template: &cross-template
stage: build stage: build
except: except:
@ -255,7 +289,7 @@ freebsd-12-x86_64:
- "_build/${CI_JOB_NAME}-report.xml" - "_build/${CI_JOB_NAME}-report.xml"
coverage: coverage:
image: registry.gitlab.gnome.org/gnome/glib/fedora:v2 image: registry.gitlab.gnome.org/gnome/glib/fedora:v3
stage: coverage stage: coverage
except: except:
- tags - tags
@ -268,7 +302,7 @@ coverage:
coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/' coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
scan-build: scan-build:
image: registry.gitlab.gnome.org/gnome/glib/fedora:v2 image: registry.gitlab.gnome.org/gnome/glib/fedora:v3
stage: analysis stage: analysis
except: except:
- tags - tags
@ -301,7 +335,7 @@ pages:
- public - public
dist-job: dist-job:
image: registry.gitlab.gnome.org/gnome/glib/fedora:v2 image: registry.gitlab.gnome.org/gnome/glib/fedora:v3
stage: build stage: build
only: only:
- tags - tags

View File

@ -47,6 +47,7 @@ RUN dnf -y install \
shared-mime-info \ shared-mime-info \
systemtap-sdt-devel \ systemtap-sdt-devel \
unzip \ unzip \
valgrind \
wget \ wget \
xz \ xz \
zlib-devel \ zlib-devel \

View File

@ -52,6 +52,7 @@ for line in args.infile:
duration = data['duration'] duration = data['duration']
return_code = data['returncode'] return_code = data['returncode']
log = data['stdout'] log = data['stdout']
log_stderr = data.get('stderr', '')
unit = { unit = {
'suite': suite_name, 'suite': suite_name,
@ -59,6 +60,7 @@ for line in args.infile:
'duration': duration, 'duration': duration,
'returncode': return_code, 'returncode': return_code,
'stdout': log, 'stdout': log,
'stderr': log_stderr,
} }
units = suites.setdefault(suite_name, []) units = suites.setdefault(suite_name, [])
@ -103,7 +105,7 @@ for name, units in suites.items():
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
failure.set('name', unit['name']) failure.set('name', unit['name'])
failure.set('type', 'error') failure.set('type', 'error')
failure.text = unit['stdout'] failure.text = unit['stdout'] + '\n' + unit['stderr']
output = ET.tostring(testsuites, encoding='unicode') output = ET.tostring(testsuites, encoding='unicode')
outfile.write(output) outfile.write(output)

View File

@ -2,10 +2,21 @@
set +e set +e
case "$1" in
--log-file)
log_file="$2"
shift
shift
;;
*)
log_file="_build/meson-logs/testlog.json"
esac
meson test \ meson test \
-C _build \ -C _build \
--timeout-multiplier ${MESON_TEST_TIMEOUT_MULTIPLIER} \ --timeout-multiplier ${MESON_TEST_TIMEOUT_MULTIPLIER} \
--no-suite flaky --no-suite flaky \
"$@"
exit_code=$? exit_code=$?
@ -13,6 +24,6 @@ python3 .gitlab-ci/meson-junit-report.py \
--project-name=glib \ --project-name=glib \
--job-id "${CI_JOB_NAME}" \ --job-id "${CI_JOB_NAME}" \
--output "_build/${CI_JOB_NAME}-report.xml" \ --output "_build/${CI_JOB_NAME}-report.xml" \
_build/meson-logs/testlog.json "${log_file}"
exit $exit_code exit $exit_code

View File

@ -798,6 +798,7 @@ test_store_past_end (void)
g_assert_cmpint (g_list_model_get_n_items (model), ==, 1); g_assert_cmpint (g_list_model_get_n_items (model), ==, 1);
item = g_list_model_get_item (model, 0); item = g_list_model_get_item (model, 0);
g_assert_nonnull (item); g_assert_nonnull (item);
g_object_unref (item);
item = g_list_model_get_item (model, G_MAXUINT); item = g_list_model_get_item (model, G_MAXUINT);
g_assert_null (item); g_assert_null (item);

View File

@ -22,6 +22,7 @@
{ {
gnutls-init-calloc gnutls-init-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:gtls_gnutls_init fun:gtls_gnutls_init
@ -30,6 +31,7 @@
{ {
gnutls-init-realloc gnutls-init-realloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:realloc fun:realloc
... ...
fun:gtls_gnutls_init fun:gtls_gnutls_init
@ -38,6 +40,7 @@
{ {
g-tls-backend-gnutls-init g-tls-backend-gnutls-init
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:g_once_impl fun:g_once_impl
fun:g_tls_backend_gnutls_init fun:g_tls_backend_gnutls_init
} }
@ -45,6 +48,7 @@
{ {
p11-tokens-init p11-tokens-init
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:create_tokens_inlock fun:create_tokens_inlock
@ -55,6 +59,7 @@
{ {
g-local-vfs-getpwnam g-local-vfs-getpwnam
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:getpwnam fun:getpwnam
@ -64,6 +69,7 @@
{ {
glib-init-malloc glib-init-malloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_quark_init fun:g_quark_init
@ -74,6 +80,7 @@
{ {
glib-init-calloc glib-init-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_quark_init fun:g_quark_init
@ -84,6 +91,7 @@
{ {
gobject-init-malloc gobject-init-malloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:gobject_init_ctor fun:gobject_init_ctor
@ -92,6 +100,7 @@
{ {
gobject-init-realloc gobject-init-realloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:realloc fun:realloc
... ...
fun:gobject_init_ctor fun:gobject_init_ctor
@ -100,6 +109,7 @@
{ {
gobject-init-calloc gobject-init-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:gobject_init_ctor fun:gobject_init_ctor
@ -108,6 +118,7 @@
{ {
g-type-register-dynamic g-type-register-dynamic
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_type_register_dynamic fun:g_type_register_dynamic
@ -116,6 +127,7 @@
{ {
g-type-register-static g-type-register-static
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_type_register_static fun:g_type_register_static
@ -124,6 +136,7 @@
{ {
g-type-register-static-realloc g-type-register-static-realloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:possible,reachable
fun:realloc fun:realloc
... ...
fun:g_type_register_static fun:g_type_register_static
@ -132,14 +145,34 @@
{ {
g-type-register-static-calloc g-type-register-static-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_type_register_static fun:g_type_register_static
} }
{
g-type-register-fundamental
Memcheck:Leak
match-leak-kinds:possible,reachable
fun:malloc
...
fun:g_type_register_fundamental
}
{
g-type-register-fundamental-calloc
Memcheck:Leak
match-leak-kinds:possible,reachable
fun:calloc
...
fun:g_type_register_fundamental
}
{ {
g-type-add-interface-dynamic g-type-add-interface-dynamic
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_type_add_interface_dynamic fun:g_type_add_interface_dynamic
@ -148,6 +181,7 @@
{ {
g-type-add-interface-static g-type-add-interface-static
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_type_add_interface_static fun:g_type_add_interface_static
@ -174,6 +208,7 @@
{ {
g-test-rand-init g-test-rand-init
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_rand_new_with_seed_array fun:g_rand_new_with_seed_array
@ -185,6 +220,7 @@
{ {
g-test-rand-init2 g-test-rand-init2
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_rand_new_with_seed_array fun:g_rand_new_with_seed_array
@ -197,6 +233,7 @@
{ {
g-quark-table-new g-quark-table-new
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:g_hash_table_new fun:g_hash_table_new
... ...
fun:quark_new fun:quark_new
@ -205,6 +242,7 @@
{ {
g-quark-table-resize g-quark-table-resize
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
... ...
fun:g_hash_table_resize fun:g_hash_table_resize
... ...
@ -214,6 +252,7 @@
{ {
g-type-interface-init g-type-interface-init
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:type_iface_vtable_base_init_Wm fun:type_iface_vtable_base_init_Wm
@ -231,6 +270,7 @@
{ {
g-type-class-init g-type-class-init
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:g_type_create_instance fun:g_type_create_instance
... ...
fun:type_class_init_Wm fun:type_class_init_Wm
@ -335,6 +375,7 @@
{ {
g-io-module-default-singleton-malloc g-io-module-default-singleton-malloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_type_create_instance fun:g_type_create_instance
@ -345,6 +386,7 @@
{ {
g-io-module-default-singleton-calloc g-io-module-default-singleton-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_type_create_instance fun:g_type_create_instance
@ -357,6 +399,7 @@
{ {
g-io-module-default-singleton g-io-module-default-singleton
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:g_type_create_instance fun:g_type_create_instance
... ...
fun:_g_io_module_get_default fun:_g_io_module_get_default
@ -365,6 +408,7 @@
{ {
g-io-module-default-singleton-module g-io-module-default-singleton-module
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_module_open fun:g_module_open
@ -375,6 +419,7 @@
{ {
g-io-module-default-singleton-name g-io-module-default-singleton-name
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_strdup fun:g_strdup
@ -385,6 +430,7 @@
{ {
g-get-language-names-malloc g-get-language-names-malloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_get_language_names fun:g_get_language_names
@ -393,6 +439,7 @@
{ {
g-get-language-names-calloc g-get-language-names-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_get_language_names fun:g_get_language_names
@ -401,6 +448,7 @@
{ {
g-static-mutex g-static-mutex
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_static_mutex_get_mutex_impl fun:g_static_mutex_get_mutex_impl
@ -409,6 +457,7 @@
{ {
g-system-thread-init g-system-thread-init
Memcheck:Leak Memcheck:Leak
match-leak-kinds:possible,reachable
fun:calloc fun:calloc
... ...
fun:g_system_thread_new fun:g_system_thread_new
@ -417,6 +466,7 @@
{ {
g-io-module-default-proxy-resolver-gnome g-io-module-default-proxy-resolver-gnome
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_proxy_resolver_gnome_init fun:g_proxy_resolver_gnome_init
@ -428,6 +478,7 @@
{ {
g-threaded-resolver-getaddrinfo-config g-threaded-resolver-getaddrinfo-config
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:__resolv_conf_allocate fun:__resolv_conf_allocate
@ -439,11 +490,11 @@
# memcheck checks that the third argument to ioctl() is a valid pointer, but # memcheck checks that the third argument to ioctl() is a valid pointer, but
# some ioctls use that argument as an integer # some ioctls use that argument as an integer
{ {
ioctl-with-non-pointer-param ioctl-with-non-pointer-param
Memcheck:Param Memcheck:Param
ioctl(generic) ioctl(generic)
fun:ioctl fun:ioctl
fun:btrfs_reflink_with_progress fun:btrfs_reflink_with_progress
} }
{ {
@ -707,9 +758,11 @@
} }
# g_set_user_dirs() deliberately leaks the previous cached g_get_user_*() values. # g_set_user_dirs() deliberately leaks the previous cached g_get_user_*() values.
# These will not all be reachable on exit.
{ {
g_set_user_dirs_str g_set_user_dirs_str
Memcheck:Leak Memcheck:Leak
match-leak-kinds:definite,reachable
fun:malloc fun:malloc
... ...
fun:set_str_if_different fun:set_str_if_different
@ -717,9 +770,11 @@
} }
# g_set_user_dirs() deliberately leaks the previous cached g_get_user_*() values. # g_set_user_dirs() deliberately leaks the previous cached g_get_user_*() values.
# These will not all be reachable on exit.
{ {
g_set_user_dirs_strv g_set_user_dirs_strv
Memcheck:Leak Memcheck:Leak
match-leak-kinds:definite,reachable
fun:malloc fun:malloc
... ...
fun:set_strv_if_different fun:set_strv_if_different
@ -730,6 +785,7 @@
{ {
g_get_system_data_dirs g_get_system_data_dirs
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_build_system_data_dirs fun:g_build_system_data_dirs
@ -740,6 +796,7 @@
{ {
g_get_user_data_dir g_get_user_data_dir
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:realloc fun:realloc
... ...
fun:g_build_user_data_dir fun:g_build_user_data_dir
@ -750,6 +807,7 @@
{ {
desktop_file_dirs_malloc desktop_file_dirs_malloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:desktop_file_dirs_lock fun:desktop_file_dirs_lock
@ -759,6 +817,7 @@
{ {
desktop_file_dirs_realloc desktop_file_dirs_realloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:realloc fun:realloc
... ...
fun:desktop_file_dirs_lock fun:desktop_file_dirs_lock
@ -768,6 +827,7 @@
{ {
desktop_file_dir_unindexed_setup_search desktop_file_dir_unindexed_setup_search
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:desktop_file_dir_unindexed_setup_search fun:desktop_file_dir_unindexed_setup_search
@ -778,6 +838,7 @@
{ {
g_io_extension_point_register g_io_extension_point_register
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_io_extension_point_register fun:g_io_extension_point_register
@ -787,6 +848,7 @@
{ {
g_strerror g_strerror
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_locale_to_utf8 fun:g_locale_to_utf8
@ -797,6 +859,7 @@
{ {
g_socket_connection_factory_register_type g_socket_connection_factory_register_type
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_socket_connection_factory_register_type fun:g_socket_connection_factory_register_type
@ -806,6 +869,7 @@
{ {
g_dbus_error_quark g_dbus_error_quark
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_dbus_error_register_error_domain fun:g_dbus_error_register_error_domain
@ -816,6 +880,7 @@
{ {
g_private_set_alloc0 g_private_set_alloc0
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_private_set_alloc0 fun:g_private_set_alloc0
@ -823,6 +888,7 @@
{ {
g_private_set_alloc0-calloc g_private_set_alloc0-calloc
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:g_private_set_alloc0 fun:g_private_set_alloc0
@ -832,6 +898,7 @@
{ {
g_main_context_push_thread_default g_main_context_push_thread_default
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:g_queue_new fun:g_queue_new
@ -842,6 +909,7 @@
{ {
g_file_info_attribute_cache g_file_info_attribute_cache
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:ensure_attribute_hash fun:ensure_attribute_hash
@ -851,6 +919,7 @@
{ {
g_file_info_attribute_cache2 g_file_info_attribute_cache2
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:ensure_attribute_hash fun:ensure_attribute_hash
@ -860,6 +929,7 @@
{ {
g_file_info_attribute_cache3 g_file_info_attribute_cache3
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:malloc fun:malloc
... ...
fun:lookup_namespace fun:lookup_namespace
@ -869,9 +939,10 @@
{ {
g_file_info_attribute_cache4 g_file_info_attribute_cache4
Memcheck:Leak Memcheck:Leak
match-leak-kinds:reachable
fun:calloc fun:calloc
... ...
fun:lookup_namespace fun:lookup_namespace
... ...
fun:g_file_* fun:g_file_*
} }

View File

@ -409,9 +409,11 @@ test_g_rec_mutex_locker (void)
g_thread_join (thread); g_thread_join (thread);
} }
/* Verify that the mutex is unlocked again */ /* Verify that the mutex is unlocked again */
thread = g_thread_new ("rec mutex unlocked", rec_mutex_unlocked_thread, &rec_mutex); thread = g_thread_new ("rec mutex unlocked", rec_mutex_unlocked_thread, &rec_mutex);
g_thread_join (thread); g_thread_join (thread);
g_rec_mutex_clear (&rec_mutex);
} }
/* Thread function to check that an rw lock given in @data cannot be writer locked */ /* Thread function to check that an rw lock given in @data cannot be writer locked */
@ -478,6 +480,8 @@ test_g_rw_lock_lockers (void)
* the locks taken above have been correctly released. */ * the locks taken above have been correctly released. */
g_assert_true (g_rw_lock_writer_trylock (&lock)); g_assert_true (g_rw_lock_writer_trylock (&lock));
g_rw_lock_writer_unlock (&lock); g_rw_lock_writer_unlock (&lock);
g_rw_lock_clear (&lock);
} }
static void static void

View File

@ -117,7 +117,7 @@ foreach test_name : python_tests
python, python,
args: ['-B', files(test_name)], args: ['-B', files(test_name)],
env: test_env, env: test_env,
suite: ['gobject'], suite: ['gobject', 'no-valgrind'],
) )
if installed_tests_enabled if installed_tests_enabled