diff --git a/test/meson.build b/test/meson.build
index 05a54d5cad2f..19726f37421d 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -7,6 +7,22 @@ endif
 
 test_enabled = true
 
+# When ASan is enabled, find the path to the ASan runtime needed by multiple
+# tests. This currently works with gcc only, as clang uses different file names
+# depending on the compiler version and target architecture.
+asan_enabled = false
+asan_runtime_missing = false
+
+if get_option('b_sanitize').contains('address')
+    asan_enabled = true
+
+    if cc.get_id() == 'gcc'
+        asan_runtime = run_command(cc, '-print-file-name=libasan.so', check : true).stdout().strip()
+    else
+        asan_runtime_missing = true
+    endif
+endif
+
 subdir('libtest')
 
 subdir('camera')
diff --git a/test/v4l2_compat/meson.build b/test/v4l2_compat/meson.build
index 10c4675286b3..da2e7a6d9045 100644
--- a/test/v4l2_compat/meson.build
+++ b/test/v4l2_compat/meson.build
@@ -4,19 +4,26 @@ if not is_variable('v4l2_compat')
     subdir_done()
 endif
 
-# If ASan is enabled, the link order runtime check will fail as v4l2-ctl and
-# v4l2-compliance are not linked to ASan. Skip the test in that case.
-#
-# TODO: Find a way to LD_PRELOAD the ASan dynamic library instead, in a
-# cross-platform way with support for both gcc and clang.
+# If ASan is enabled but the ASan runtime shared library missing,
+# v4l2_compat_test.py won't be able to LD_PRELOAD it, resulting in a link order
+# runtime check failure as v4l2-ctl and v4l2-compliance are not linked to ASan.
+# Skip the test in that case.
 
-if get_option('b_sanitize').contains('address')
+if asan_runtime_missing
+    warning('Unable to get path to ASan runtime, v4l2_compat test disabled')
     subdir_done()
 endif
 
 v4l2_compat_test = files('v4l2_compat_test.py')
+v4l2_compat_args = []
+
+if asan_enabled
+    v4l2_compat_args += ['-s', asan_runtime]
+endif
+
+v4l2_compat_args += [v4l2_compat]
 
 test('v4l2_compat_test', v4l2_compat_test,
-     args : v4l2_compat,
+     args : v4l2_compat_args,
      suite : 'v4l2_compat',
      timeout : 60)
diff --git a/test/v4l2_compat/v4l2_compat_test.py b/test/v4l2_compat/v4l2_compat_test.py
index a77585fc2f49..bd89d4962c16 100755
--- a/test/v4l2_compat/v4l2_compat_test.py
+++ b/test/v4l2_compat/v4l2_compat_test.py
@@ -57,8 +57,8 @@ def extract_result(result):
     return ret
 
 
-def test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, base_driver):
-    ret, output = run_with_stdout(v4l2_compliance, '-s', '-d', device, env={'LD_PRELOAD': v4l2_compat})
+def test_v4l2_compliance(v4l2_compliance, ld_preload, device, base_driver):
+    ret, output = run_with_stdout(v4l2_compliance, '-s', '-d', device, env={'LD_PRELOAD': ld_preload})
     if ret < 0:
         output.append(f'Test for {device} terminated due to signal {signal.Signals(-ret).name}')
         return TestFail, output
@@ -82,13 +82,21 @@ def main(argv):
     parser = argparse.ArgumentParser()
     parser.add_argument('-a', '--all', action='store_true',
                         help='Test all available cameras')
+    parser.add_argument('-s', '--sanitizer', type=str,
+                        help='Path to the address sanitizer (ASan) runtime')
     parser.add_argument('-v', '--verbose', action='store_true',
                         help='Make the output verbose')
     parser.add_argument('v4l2_compat', type=str,
                         help='Path to v4l2-compat.so')
     args = parser.parse_args(argv[1:])
 
-    v4l2_compat = args.v4l2_compat
+    # Compute the LD_PRELOAD value by first loading ASan (if specified) and
+    # then the V4L2 compat layer.
+    ld_preload = []
+    if args.sanitizer:
+        ld_preload.append(args.sanitizer)
+    ld_preload.append(args.v4l2_compat)
+    ld_preload = ':'.join(ld_preload)
 
     v4l2_compliance = shutil.which('v4l2-compliance')
     if v4l2_compliance is None:
@@ -118,7 +126,7 @@ def main(argv):
     failed = []
     drivers_tested = {}
     for device in dev_nodes:
-        ret, out = run_with_stdout(v4l2_ctl, '-D', '-d', device, env={'LD_PRELOAD': v4l2_compat})
+        ret, out = run_with_stdout(v4l2_ctl, '-D', '-d', device, env={'LD_PRELOAD': ld_preload})
         if ret < 0:
             failed.append(device)
             print(f'v4l2-ctl failed on {device} with v4l2-compat')
@@ -144,7 +152,7 @@ def main(argv):
             continue
 
         print(f'Testing {device} with {driver} driver... ', end='')
-        ret, msg = test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, driver)
+        ret, msg = test_v4l2_compliance(v4l2_compliance, ld_preload, device, driver)
         if ret == TestFail:
             failed.append(device)
             print('failed')
