diff --git a/pressure-vessel/adverb.1.md b/pressure-vessel/adverb.1.md
index 85fe81fb806b471217c349dcff3aae509106d8f3..8ebdbbdb9833d60b739a5d0bf259d0559bfe0b72 100644
--- a/pressure-vessel/adverb.1.md
+++ b/pressure-vessel/adverb.1.md
@@ -18,8 +18,8 @@ pressure-vessel-adverb - wrap processes in various ways
 [**--[no-]exit-with-parent**]
 [**--fd** *FD*...]
 [**--[no-]generate-locales**]
-[**--ld-audit** *MODULE*...]
-[**--ld-preload** *MODULE*...]
+[**--ld-audit** *MODULE*[**:arch=***TUPLE*]...]
+[**--ld-preload** *MODULE*[**:**...]...]
 [**--pass-fd** *FD*...]
 [**--shell** **none**|**after**|**fail**|**instead**]
 [**--subreaper**]
@@ -70,15 +70,27 @@ exit status.
     **LOCPATH** environment variable.
     **--no-generate-locales** disables this behaviour, and is the default.
 
-**--ld-audit** *MODULE*
+**--ld-audit** *MODULE*[**:arch=***TUPLE*]
 :   Add *MODULE* to **LD_AUDIT** before executing *COMMAND*.
+    The optional *TUPLE* is the same as for **--ld-preload**, below.
 
-**--ld-preload** *MODULE*
+**--ld-preload** *MODULE*[**:arch=***TUPLE*]
 :   Add *MODULE* to **LD_PRELOAD** before executing *COMMAND*.
-    Some adjustments may be performed to the provided *MODULE*, e.g.
-    multiple preloads of gameoverlayrenderer.so for different ABIs may be
-    joined together into a single path by leveraging the dynamic linker
-    token expansion feature.
+
+    If the optional **:arch=***TUPLE* is given, the *MODULE* is only used for
+    the given architecture, and is paired with other modules (if any) that
+    share its basename; for example,
+    `/home/me/.steam/root/ubuntu12_32/gameoverlayrenderer.so:arch=i386-linux-gnu`
+    and
+    `/home/me/.steam/root/ubuntu12_64/gameoverlayrenderer.so:arch=x86_64-linux-gnu`
+    will be combined into a single **LD_PRELOAD** entry of the form
+    `/tmp/pressure-vessel-libs-123456/${PLATFORM}/gameoverlayrenderer.so`.
+
+    For a **LD_PRELOAD** module named `gameoverlayrenderer.so` in a directory
+    named `ubuntu12_32` or `ubuntu12_64`, the architecture is automatically
+    set to `i386-linux-gnu` or `x86_64-linux-gnu` respectively, if not
+    otherwise given. Other special-case behaviour might be added in future
+    if required.
 
 **--lock-file** *FILENAME*
 :   Lock the file *FILENAME* according to the most recently seen
diff --git a/pressure-vessel/adverb.c b/pressure-vessel/adverb.c
index b5ef2b9a099924a157542b51b60b7709ecf7f604..12056a0a669c86e26a467c39d965bd0582da4782 100644
--- a/pressure-vessel/adverb.c
+++ b/pressure-vessel/adverb.c
@@ -76,24 +76,70 @@ typedef struct
 {
   gchar *root_path;
   gchar *platform_token_path;
-  GHashTable *abi_paths;
+  /* Same order as pv_multiarch_details */
+  gchar *abi_paths[PV_N_SUPPORTED_ARCHITECTURES];
 } LibTempDirs;
 
-static PreloadModule opt_preload_modules[] =
+typedef enum
 {
-  { "LD_AUDIT", NULL },
-  { "LD_PRELOAD", NULL },
+  PRELOAD_VARIABLE_INDEX_LD_AUDIT,
+  PRELOAD_VARIABLE_INDEX_LD_PRELOAD,
+} PreloadVariableIndex;
+
+/* Indexed by PreloadVariableIndex */
+static const char *preload_variables[] =
+{
+  "LD_AUDIT",
+  "LD_PRELOAD",
 };
 
+typedef struct
+{
+  char *name;
+  gsize index_in_preload_variables;
+  /* An index in pv_multiarch_details, or G_MAXSIZE if unspecified */
+  gsize abi_index;
+} AdverbPreloadModule;
+
+static void
+adverb_preload_module_clear (gpointer p)
+{
+  AdverbPreloadModule *self = p;
+
+  g_free (self->name);
+}
+
+static GArray *opt_preload_modules = NULL;
+
+static gpointer
+generic_strdup (gpointer p)
+{
+  return g_strdup (p);
+}
+
+static void
+ptr_array_add_unique (GPtrArray *arr,
+                      const void *item,
+                      GEqualFunc equal_func,
+                      GBoxedCopyFunc copy_func)
+{
+  if (!g_ptr_array_find_with_equal_func (arr, item, equal_func, NULL))
+    g_ptr_array_add (arr, copy_func ((gpointer) item));
+}
+
 static void
 lib_temp_dirs_free (LibTempDirs *lib_temp_dirs)
 {
+  gsize abi;
+
   if (lib_temp_dirs->root_path != NULL)
     _srt_rm_rf (lib_temp_dirs->root_path);
 
   g_clear_pointer (&lib_temp_dirs->root_path, g_free);
   g_clear_pointer (&lib_temp_dirs->platform_token_path, g_free);
-  g_clear_pointer (&lib_temp_dirs->abi_paths, g_hash_table_unref);
+
+  for (abi = 0; abi < G_N_ELEMENTS (lib_temp_dirs->abi_paths); abi++)
+    g_clear_pointer (&lib_temp_dirs->abi_paths[abi], g_free);
 
   g_free (lib_temp_dirs);
 }
@@ -205,15 +251,80 @@ opt_fd_cb (const char *name,
   return TRUE;
 }
 
+static gboolean
+opt_ld_something (const char *option,
+                  gsize index_in_preload_variables,
+                  const char *value,
+                  gpointer data,
+                  GError **error)
+{
+  AdverbPreloadModule module = { NULL, 0, G_MAXSIZE };
+  g_auto(GStrv) parts = NULL;
+  const char *architecture = NULL;
+
+  parts = g_strsplit (value, ":", 0);
+
+  if (parts[0] != NULL)
+    {
+      gsize i;
+
+      for (i = 1; parts[i] != NULL; i++)
+        {
+          if (g_str_has_prefix (parts[i], "abi="))
+            {
+              gsize abi;
+
+              architecture = parts[i] + strlen ("abi=");
+
+              for (abi = 0; abi < PV_N_SUPPORTED_ARCHITECTURES; abi++)
+                {
+                  if (strcmp (architecture, pv_multiarch_details[abi].tuple) == 0)
+                    {
+                      module.abi_index = abi;
+                      break;
+                    }
+                }
+
+              if (module.abi_index == G_MAXSIZE)
+                {
+                  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                               "Unsupported ABI %s",
+                               architecture);
+                  return FALSE;
+                }
+            }
+          else
+            {
+              g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                           "Unexpected option in %s=\"%s\": %s",
+                           option, value, parts[i]);
+              return FALSE;
+            }
+        }
+
+      value = parts[0];
+    }
+
+  if (opt_preload_modules == NULL)
+    {
+      opt_preload_modules = g_array_new (FALSE, FALSE, sizeof (AdverbPreloadModule));
+      g_array_set_clear_func (opt_preload_modules, adverb_preload_module_clear);
+    }
+
+  module.index_in_preload_variables = index_in_preload_variables;
+  module.name = g_strdup (value);
+  g_array_append_val (opt_preload_modules, module);
+  return TRUE;
+}
+
 static gboolean
 opt_ld_audit_cb (const gchar *option_name,
                  const gchar *value,
                  gpointer data,
                  GError **error)
 {
-  pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules),
-                            "LD_AUDIT", value);
-  return TRUE;
+  return opt_ld_something (option_name, PRELOAD_VARIABLE_INDEX_LD_AUDIT,
+                           value, data, error);
 }
 
 static gboolean
@@ -222,9 +333,8 @@ opt_ld_preload_cb (const gchar *option_name,
                    gpointer data,
                    GError **error)
 {
-  pv_append_preload_module (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules),
-                            "LD_PRELOAD", value);
-  return TRUE;
+  return opt_ld_something (option_name, PRELOAD_VARIABLE_INDEX_LD_PRELOAD,
+                           value, data, error);
 }
 
 static gboolean
@@ -462,7 +572,6 @@ generate_lib_temp_dirs (LibTempDirs *lib_temp_dirs,
   gsize abi;
 
   g_return_val_if_fail (lib_temp_dirs != NULL, FALSE);
-  g_return_val_if_fail (lib_temp_dirs->abi_paths == NULL, FALSE);
 
   info = srt_system_info_new (NULL);
 
@@ -474,27 +583,34 @@ generate_lib_temp_dirs (LibTempDirs *lib_temp_dirs,
   lib_temp_dirs->platform_token_path = g_build_filename (lib_temp_dirs->root_path,
                                                          "${PLATFORM}", NULL);
 
-  lib_temp_dirs->abi_paths = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
   for (abi = 0; abi < PV_N_SUPPORTED_ARCHITECTURES; abi++)
     {
       g_autofree gchar *libdl_platform = NULL;
       g_autofree gchar *abi_path = NULL;
-      libdl_platform = srt_system_info_dup_libdl_platform (info,
-                                                           pv_multiarch_details[abi].tuple,
-                                                           error);
-      if (!libdl_platform)
-        return glnx_prefix_error (error,
-                                  "Unknown expansion of the dl string token $PLATFORM");
+
+      if (g_getenv ("PRESSURE_VESSEL_TEST_STANDARDIZE_PLATFORM") != NULL)
+        {
+          /* In unit tests it isn't straightforward to find the real
+           * ${PLATFORM}, so we use a predictable mock implementation:
+           * whichever platform happens to be listed first. */
+          libdl_platform = g_strdup (pv_multiarch_details[abi].platforms[0]);
+        }
+      else
+        {
+          libdl_platform = srt_system_info_dup_libdl_platform (info,
+                                                               pv_multiarch_details[abi].tuple,
+                                                               error);
+          if (!libdl_platform)
+            return glnx_prefix_error (error,
+                                      "Unknown expansion of the dl string token $PLATFORM");
+        }
 
       abi_path = g_build_filename (lib_temp_dirs->root_path, libdl_platform, NULL);
 
       if (g_mkdir (abi_path, 0700) != 0)
         return glnx_throw_errno_prefix (error, "Unable to create \"%s\"", abi_path);
 
-      g_hash_table_insert (lib_temp_dirs->abi_paths,
-                           g_strdup (pv_multiarch_details[abi].tuple),
-                           g_steal_pointer (&abi_path));
+      lib_temp_dirs->abi_paths[abi] = g_steal_pointer (&abi_path);
     }
 
   return TRUE;
@@ -932,57 +1048,46 @@ main (int argc,
       g_clear_error (error);
     }
 
-  for (i = 0; i < G_N_ELEMENTS (opt_preload_modules); i++)
+  if (opt_preload_modules != NULL)
     {
-      const char *variable = opt_preload_modules[i].variable;
-      const GPtrArray *values = opt_preload_modules[i].values;
-      g_autofree gchar *platform_overlay_path = NULL;
-      g_autoptr(GPtrArray) search_path = NULL;
-      g_autoptr(GString) buffer = NULL;
-      gsize j;
-
-      if (values == NULL)
-        continue;
+      GPtrArray *preload_search_paths[G_N_ELEMENTS (preload_variables)] = { NULL };
 
-      search_path = g_ptr_array_new_with_free_func (g_free);
-      buffer = g_string_new ("");
-
-      if (g_strcmp0 (variable, "LD_PRELOAD") != 0 || !all_abi_paths_created)
+      /* Iterate through all modules, populating preload_search_paths */
+      for (i = 0; i < opt_preload_modules->len; i++)
         {
-          /* Currently we perform adjustments only for LD_PRELOAD.
-           * Also if we were not able to create the temporary libraries
-           * directories, we simply avoid any adjustment and try to continue */
-          for (j = 0; j < values->len; j++)
-            {
-              const char *preload = g_ptr_array_index (values, j);
-              g_assert (preload != NULL);
-              if (*preload == '\0')
-                continue;
+          const AdverbPreloadModule *module = &g_array_index (opt_preload_modules,
+                                                              AdverbPreloadModule, i);
+          GPtrArray *search_path = preload_search_paths[module->index_in_preload_variables];
+          const char *preload = module->name;
+          const char *base;
+          gsize abi_index = module->abi_index;
 
-              pv_search_path_append (buffer, preload);
-            }
-
-          if (buffer->len != 0)
-            flatpak_bwrap_set_env (wrapped_command, variable, buffer->str, TRUE);
-
-          /* No adjustment needed, continue to the next preload module */
-          continue;
-        }
-
-      g_debug ("Adjusting %s...", variable);
-      platform_overlay_path = g_build_filename (lib_temp_dirs->platform_token_path,
-                                               "gameoverlayrenderer.so", NULL);
-      for (j = 0; j < values->len; j++)
-        {
-          const char *preload = g_ptr_array_index (values, j);
           g_assert (preload != NULL);
+
           if (*preload == '\0')
             continue;
 
-          if (g_str_has_suffix (preload, "/gameoverlayrenderer.so"))
+          base = glnx_basename (preload);
+
+          if (search_path == NULL)
             {
-              g_autofree gchar *link = NULL;
+              preload_search_paths[module->index_in_preload_variables]
+                = search_path
+                = g_ptr_array_new_full (opt_preload_modules->len, g_free);
+            }
 
+          /* If we were not able to create the temporary library
+           * directories, we simply avoid any adjustment and try to continue */
+          if (!all_abi_paths_created)
+            {
+              g_ptr_array_add (search_path, g_strdup (preload));
+              continue;
+            }
+
+          if (abi_index == G_MAXSIZE
+              && module->index_in_preload_variables == PRELOAD_VARIABLE_INDEX_LD_PRELOAD
+              && strcmp (base, "gameoverlayrenderer.so") == 0)
+            {
               for (gsize abi = 0; abi < PV_N_SUPPORTED_ARCHITECTURES; abi++)
                 {
                   g_autofree gchar *expected_suffix = g_strdup_printf ("/%s/gameoverlayrenderer.so",
@@ -990,20 +1095,30 @@ main (int argc,
 
                   if (g_str_has_suffix (preload, expected_suffix))
                     {
-                      link = g_build_filename (g_hash_table_lookup (lib_temp_dirs->abi_paths,
-                                                                    pv_multiarch_details[abi].tuple),
-                                               "gameoverlayrenderer.so", NULL);
+                      abi_index = abi;
                       break;
                     }
                 }
 
-              if (link == NULL)
+              if (abi_index == G_MAXSIZE)
                 {
-                  g_ptr_array_add (search_path, g_strdup (preload));
-                  g_debug ("Preloading gameoverlayrenderer.so from an unexpected path \"%s\", "
-                           "just leave it as is without adjusting", preload);
-                  continue;
+                  g_debug ("Preloading %s from an unexpected path \"%s\", "
+                           "just leave it as is without adjusting",
+                           base, preload);
                 }
+            }
+
+          if (abi_index != G_MAXSIZE)
+            {
+              g_autofree gchar *link = NULL;
+              g_autofree gchar *platform_path = NULL;
+
+              g_debug ("Module %s is for %s",
+                       preload, pv_multiarch_details[abi_index].tuple);
+              platform_path = g_build_filename (lib_temp_dirs->platform_token_path,
+                                                base, NULL);
+              link = g_build_filename (lib_temp_dirs->abi_paths[abi_index],
+                                       base, NULL);
 
               if (symlink (preload, link) != 0)
                 {
@@ -1015,22 +1130,32 @@ main (int argc,
                                            link, preload);
                   goto out;
                 }
-              g_debug ("created symlink %s -> %s", link, preload);
 
-              if (!g_ptr_array_find_with_equal_func (search_path, platform_overlay_path,
-                                                     g_str_equal, NULL))
-                g_ptr_array_add (search_path, g_strdup (platform_overlay_path));
+              g_debug ("created symlink %s -> %s", link, preload);
+              ptr_array_add_unique (search_path, platform_path,
+                                    g_str_equal, generic_strdup);
             }
           else
             {
+              g_debug ("Module %s is for all architectures", preload);
               g_ptr_array_add (search_path, g_strdup (preload));
             }
         }
 
-      g_ptr_array_foreach (search_path, (GFunc) append_to_search_path, buffer);
+      /* Serialize search_paths[PRELOAD_VARIABLE_INDEX_LD_AUDIT] into
+       * LD_AUDIT, etc. */
+      for (i = 0; i < G_N_ELEMENTS (preload_variables); i++)
+        {
+          GPtrArray *search_path = preload_search_paths[i];
+          g_autoptr(GString) buffer = g_string_new ("");
+          const char *variable = preload_variables[i];
+
+          if (search_path != NULL)
+            g_ptr_array_foreach (search_path, (GFunc) append_to_search_path, buffer);
 
-      if (buffer->len != 0)
-        flatpak_bwrap_set_env (wrapped_command, variable, buffer->str, TRUE);
+          if (buffer->len != 0)
+            flatpak_bwrap_set_env (wrapped_command, variable, buffer->str, TRUE);
+        }
     }
 
   if (opt_generate_locales)
@@ -1190,7 +1315,7 @@ out:
   if (locales_temp_dir != NULL)
     _srt_rm_rf (locales_temp_dir);
 
-  pv_preload_modules_free (opt_preload_modules, G_N_ELEMENTS (opt_preload_modules));
+  g_clear_pointer (&opt_preload_modules, g_array_unref);
 
   if (local_error != NULL)
     pv_log_failure ("%s", local_error->message);
diff --git a/tests/pressure-vessel/adverb.py b/tests/pressure-vessel/adverb.py
index 9088e43e7d7b9b76e7cb2ba3eb9ab94810e7ed44..0c176d88d880ee69028037d96794853323ab3792 100755
--- a/tests/pressure-vessel/adverb.py
+++ b/tests/pressure-vessel/adverb.py
@@ -5,6 +5,7 @@
 
 import logging
 import os
+import re
 import signal
 import subprocess
 import sys
@@ -18,6 +19,7 @@ except ImportError:
 
 from testutils import (
     BaseTest,
+    run_subprocess,
     test_main,
 )
 
@@ -25,21 +27,156 @@ from testutils import (
 logger = logging.getLogger('test-adverb')
 
 
+EX_USAGE = 64
+
+
 class TestAdverb(BaseTest):
+    def run_subprocess(
+        self,
+        args,           # type: typing.Union[typing.List[str], str]
+        check=False,
+        input=None,     # type: typing.Optional[bytes]
+        timeout=None,   # type: typing.Optional[int]
+        **kwargs        # type: typing.Any
+    ):
+        logger.info('Running: %r', args)
+        return run_subprocess(
+            args, check=check, input=input, timeout=timeout, **kwargs
+        )
+
     def setUp(self) -> None:
         super().setUp()
 
         if 'PRESSURE_VESSEL_UNINSTALLED' in os.environ:
             self.adverb = self.command_prefix + [
+                'env',
+                '-u', 'LD_AUDIT',
+                '-u', 'LD_PRELOAD',
+                # In unit tests it isn't straightforward to find the real
+                # ${PLATFORM}, so we use a predictable mock implementation
+                # that always uses PvMultiarchDetails.platforms[0].
+                'PRESSURE_VESSEL_TEST_STANDARDIZE_PLATFORM=1',
                 os.path.join(
                     self.top_builddir,
                     'pressure-vessel',
                     'pressure-vessel-adverb'
                 ),
             ]
+            self.helper = self.command_prefix + [
+                os.path.join(
+                    self.top_builddir,
+                    'tests',
+                    'pressure-vessel',
+                    'test-helper'
+                ),
+            ]
         else:
             self.skipTest('Not available as an installed-test')
 
+    def test_ld_preload(self) -> None:
+        completed = run_subprocess(
+            self.adverb + [
+                '--ld-audit=/nonexistent/libaudit.so',
+                '--ld-preload=/nonexistent/libpreload.so',
+                '--ld-preload=/nonexistent/ubuntu12_32/gameoverlayrenderer.so',
+                '--ld-preload=/nonexistent/ubuntu12_64/gameoverlayrenderer.so',
+                ('--ld-preload'
+                 '=/nonexistent/lib32/libMangoHud.so'
+                 ':abi=i386-linux-gnu'),
+                ('--ld-preload'
+                 '=/nonexistent/lib64/libMangoHud.so'
+                 ':abi=x86_64-linux-gnu'),
+                ('--ld-preload'
+                 '=/nonexistent/lib64/64-bit-only.so'
+                 ':abi=x86_64-linux-gnu'),
+                '--',
+                'sh', '-euc',
+                # The hard-coded i686 and xeon_phi here must match up with
+                # pv_multiarch_details[i].platforms[0], which is what is used
+                # as a mock implementation under
+                # PRESSURE_VESSEL_TEST_STANDARDIZE_PLATFORM=1.
+                r'''
+                ld_audit="$LD_AUDIT"
+                ld_preload="$LD_PRELOAD"
+                unset LD_AUDIT
+                unset LD_PRELOAD
+
+                echo "LD_AUDIT=$ld_audit"
+                echo "LD_PRELOAD=$ld_preload"
+
+                IFS=:
+                for item in $ld_preload; do
+                    case "$item" in
+                        (*\$\{PLATFORM\}*)
+                            i686="$(echo "$item" |
+                                sed -e 's/[$]{PLATFORM}/i686/g')"
+                            xeon_phi="$(echo "$item" |
+                                sed -e 's/[$]{PLATFORM}/xeon_phi/g')"
+                            printf "i686: symlink to "
+                            readlink "$i686" || echo "(nothing)"
+                            printf "xeon_phi: symlink to "
+                            readlink "$xeon_phi" || echo "(nothing)"
+                            ;;
+                        (*)
+                            echo "literal $item"
+                            ;;
+                    esac
+                done
+                ''',
+            ],
+            check=True,
+            stdin=subprocess.PIPE,
+            stdout=subprocess.PIPE,
+            stderr=2,
+            universal_newlines=True,
+        )
+
+        stdout = completed.stdout
+        assert stdout is not None
+        lines = stdout.splitlines()
+        self.assertEqual(
+            lines[0],
+            'LD_AUDIT=/nonexistent/libaudit.so',
+        )
+        self.assertEqual(
+            re.sub(r':/[^:]*?/pressure-vessel-libs-....../',
+                   r':/tmp/pressure-vessel-libs-XXXXXX/',
+                   lines[1]),
+            ('LD_PRELOAD=/nonexistent/libpreload.so'
+             ':/tmp/pressure-vessel-libs-XXXXXX/'
+             '${PLATFORM}/gameoverlayrenderer.so'
+             ':/tmp/pressure-vessel-libs-XXXXXX/'
+             '${PLATFORM}/libMangoHud.so'
+             ':/tmp/pressure-vessel-libs-XXXXXX/'
+             '${PLATFORM}/64-bit-only.so')
+        )
+        self.assertEqual(lines[2], 'literal /nonexistent/libpreload.so')
+        self.assertEqual(
+            lines[3],
+            'i686: symlink to /nonexistent/ubuntu12_32/gameoverlayrenderer.so',
+        )
+        self.assertEqual(
+            lines[4],
+            ('xeon_phi: symlink to '
+             '/nonexistent/ubuntu12_64/gameoverlayrenderer.so'),
+        )
+        self.assertEqual(
+            lines[5],
+            'i686: symlink to /nonexistent/lib32/libMangoHud.so',
+        )
+        self.assertEqual(
+            lines[6],
+            'xeon_phi: symlink to /nonexistent/lib64/libMangoHud.so',
+        )
+        self.assertEqual(
+            lines[7],
+            'i686: symlink to (nothing)',
+        )
+        self.assertEqual(
+            lines[8],
+            'xeon_phi: symlink to /nonexistent/lib64/64-bit-only.so',
+        )
+
     def test_stdio_passthrough(self) -> None:
         proc = subprocess.Popen(
             self.adverb + [
@@ -106,6 +243,29 @@ class TestAdverb(BaseTest):
             proc.wait()
             self.assertEqual(proc.returncode, 0)
 
+    def test_wrong_options(self) -> None:
+        for option in (
+            '--an-unknown-option',
+            '--ld-preload=/nonexistent/libfoo.so:abi=hal9000-movieos',
+            '--ld-preload=/nonexistent/libfoo.so:abi=i386-linux-gnu:foo',
+            '--ld-preload=/nonexistent/libfoo.so:foo=bar',
+            '--pass-fd=-1',
+            '--shell=wrong',
+            '--terminal=wrong',
+        ):
+            proc = subprocess.Popen(
+                self.adverb + [
+                    option,
+                    '--',
+                    'sh', '-euc', 'exit 42',
+                ],
+                stdout=2,
+                stderr=2,
+                universal_newlines=True,
+            )
+            proc.wait()
+            self.assertEqual(proc.returncode, EX_USAGE)
+
     def tearDown(self) -> None:
         super().tearDown()