From a79679cd3083b2c09e75390b047d4351456427e6 Mon Sep 17 00:00:00 2001 From: Caleb Sander Date: Fri, 13 Oct 2023 19:13:56 -0600 Subject: [PATCH] test: make LD_PRELOAD tests work with ASAN Several tests mock libc functions by setting LD_PRELOAD to a shared library containing mock implementations of the functions. Currently this prevents the tests from running with ASAN. ASAN complains that libasan doesn't come first in LD_PRELOAD and aborts. But in practice this doesn't seem to be an issue. Sample ASAN issues added to libnvme, the test cases, and the mocks are all correctly reported. So suppress this warning by setting the environment variable ASAN_OPTIONS=verify_asan_link_order=0. In case the user does want to inject a specific libasan, change the tests' use of LD_PRELOAD to append the mock shared library rather than overwriting LD_PRELOAD entirely. Signed-off-by: Caleb Sander --- test/ioctl/meson.build | 16 +++++++++++++--- test/meson.build | 7 ++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/test/ioctl/meson.build b/test/ioctl/meson.build index edbe6b35..b329d270 100644 --- a/test/ioctl/meson.build +++ b/test/ioctl/meson.build @@ -3,6 +3,16 @@ mock_ioctl = library( ['mock.c', 'util.c'], ) +# Add mock-ioctl to the LD_PRELOAD path so it overrides libc. +# Append to LD_PRELOAD so existing libraries, e.g. libasan, are kept. +# If libasan isn't specified in the LD_PRELOAD path, ASAN warns about mock-ioctl +# being loaded first because its memory allocations might not get intercepted. +# But it appears this isn't a problem; ASAN errors in mock-ioctl are reported. +# This is likely because the executable still links with libasan before libc. +mock_ioctl_env = environment() +mock_ioctl_env.append('LD_PRELOAD', mock_ioctl.full_path()) +mock_ioctl_env.set('ASAN_OPTIONS', 'verify_asan_link_order=0') + discovery = executable( 'test-discovery', 'discovery.c', @@ -11,7 +21,7 @@ discovery = executable( link_with: mock_ioctl, ) -test('discovery', discovery, env: ['LD_PRELOAD=' + mock_ioctl.full_path()]) +test('discovery', discovery, env: mock_ioctl_env) features = executable( 'test-features', @@ -20,7 +30,7 @@ features = executable( link_with: mock_ioctl, ) -test('features', features, env: ['LD_PRELOAD=' + mock_ioctl.full_path()]) +test('features', features, env: mock_ioctl_env) identify = executable( 'test-identify', @@ -29,4 +39,4 @@ identify = executable( link_with: mock_ioctl, ) -test('identify', identify, env: ['LD_PRELOAD=' + mock_ioctl.full_path()]) +test('identify', identify, env: mock_ioctl_env) diff --git a/test/meson.build b/test/meson.build index 0c458794..71be57c0 100644 --- a/test/meson.build +++ b/test/meson.build @@ -72,6 +72,11 @@ if conf.get('HAVE_NETDB') ['mock-ifaddrs.c', ], ) + # See comment in test/ioctl/meson.build explaining how LD_PRELOAD is used + mock_ifaddrs_env = environment() + mock_ifaddrs_env.append('LD_PRELOAD', mock_ifaddrs.full_path()) + mock_ifaddrs_env.set('ASAN_OPTIONS', 'verify_asan_link_order=0') + tree = executable( 'tree', ['tree.c'], @@ -80,7 +85,7 @@ if conf.get('HAVE_NETDB') link_with: mock_ifaddrs, ) - test('tree', tree, env: ['LD_PRELOAD=' + mock_ifaddrs.full_path()]) + test('tree', tree, env: mock_ifaddrs_env) test_util = executable( 'test-util', -- 2.50.1