diff --git a/bin/check-requirements.c b/bin/check-requirements.c
index 3f26d11bbcf629d963410d1dbad97fa9c86f4bb1..d7e28b0c60b757b3aef567b7337ad66f1b07de1b 100644
--- a/bin/check-requirements.c
+++ b/bin/check-requirements.c
@@ -100,6 +100,8 @@ main (int argc,
   int opt;
   int exit_code = EXIT_SUCCESS;
 
+  _srt_setenv_disable_gio_modules ();
+
   while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1)
     {
       switch (opt)
diff --git a/bin/meson.build b/bin/meson.build
index 01ff7eb7ee4619e765496b988b0858f2fdad300d..897d3c989a8c840e35be47f2352373f30eeb3493 100644
--- a/bin/meson.build
+++ b/bin/meson.build
@@ -24,10 +24,9 @@
 executable(
   'steam-runtime-system-info',
   'system-info.c',
-  dependencies : [gio_unix, glib, json_glib, libglnx_dep, libsteamrt_dep],
+  dependencies : [gio_unix, glib, json_glib, libglnx_dep, libsteamrt_static_dep],
   install : true,
-  # Use the adjacent libsteam-runtime-tools and json-glib, ignoring
-  # LD_LIBRARY_PATH even if set
+  # Use the adjacent json-glib, ignoring LD_LIBRARY_PATH even if set
   build_rpath : bin_rpath,
   install_rpath : bin_rpath,
 )
@@ -35,10 +34,9 @@ executable(
 executable(
   'steam-runtime-check-requirements',
   'check-requirements.c',
-  dependencies : [glib, json_glib, gobject, libsteamrt_dep],
+  dependencies : [glib, json_glib, gobject, libsteamrt_static_dep],
   install : true,
-  # Use the adjacent libsteam-runtime-tools and json-glib, ignoring
-  # LD_LIBRARY_PATH even if set
+  # Use the adjacent json-glib, ignoring LD_LIBRARY_PATH even if set
   build_rpath : bin_rpath,
   install_rpath : bin_rpath,
 )
diff --git a/bin/system-info.c b/bin/system-info.c
index 66dab2c992cf84f72fa3a7bf77459e2d6c92a892..18c922f6be26cccf4c12b38a70df27dc8ef843e4 100644
--- a/bin/system-info.c
+++ b/bin/system-info.c
@@ -807,6 +807,8 @@ main (int argc,
   const GList *icd_iter;
   SrtDriverFlags extra_driver_flags = SRT_DRIVER_FLAGS_INCLUDE_ALL;
 
+  _srt_setenv_disable_gio_modules ();
+
   while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1)
     {
       switch (opt)
diff --git a/debian/libsteam-runtime-tools-0-0.symbols b/debian/libsteam-runtime-tools-0-0.symbols
index dea1f89f24355e51845b6cb19b8f9aa62af3ab11..cf81c65f9bd301cc9977e15cd25b0328bec0e699 100644
--- a/debian/libsteam-runtime-tools-0-0.symbols
+++ b/debian/libsteam-runtime-tools-0-0.symbols
@@ -1,7 +1,6 @@
 libsteam-runtime-tools-0.so.0 libsteam-runtime-tools-0-0 #MINVER#
 * Build-Depends-Package: libsteam-runtime-tools-0-dev
  _srt_divert_stdout_to_stderr@Base 0.20201002.0
- _srt_filter_gameoverlayrenderer@Base 0.20190822.0
  _srt_rm_rf@Base 0.20200306.0
  _srt_unblock_signals@Base 0.20200109.0
  srt_add_flag_from_nick@Base 0.20200908.0
diff --git a/pressure-vessel/adverb.c b/pressure-vessel/adverb.c
index 21f5b5896c2abed3ea3507683f2ccbc4249cbdb3..1c3f01261d9db26edfe73ea0788770cb408bf39f 100644
--- a/pressure-vessel/adverb.c
+++ b/pressure-vessel/adverb.c
@@ -717,7 +717,7 @@ main (int argc,
       goto out;
     }
 
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   if (argc >= 2 && strcmp (argv[1], "--") == 0)
     {
diff --git a/pressure-vessel/launch.c b/pressure-vessel/launch.c
index a6d12e42367aa32818931bef7127dfe66c067286..d000bc32eb3e0ba462084df750fe68b5eed3a902 100644
--- a/pressure-vessel/launch.c
+++ b/pressure-vessel/launch.c
@@ -619,7 +619,7 @@ main (int argc,
         }
     }
 
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   if (launcher_api.service_bus_name != NULL && opt_socket != NULL)
     {
diff --git a/pressure-vessel/launcher.c b/pressure-vessel/launcher.c
index 68618b54eb78f81fa7fd50c241c4226223f7c84d..4acd2c1f28ac4438ca41414a8a5b56a427c48a2c 100644
--- a/pressure-vessel/launcher.c
+++ b/pressure-vessel/launcher.c
@@ -1232,7 +1232,7 @@ main (int argc,
       goto out;
     }
 
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   if (argc >= 2 && strcmp (argv[1], "--") == 0)
     {
diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c
index 5c4add5b7ce75b9456a4325f07800ad8c1031dd9..d82cb81380f406b63b4e3dbb20c41d6f857c9b16 100644
--- a/pressure-vessel/utils.c
+++ b/pressure-vessel/utils.c
@@ -47,27 +47,6 @@ child_setup_cb (gpointer user_data)
   flatpak_close_fds_workaround (3);
 }
 
-/**
- * pv_avoid_gvfs:
- *
- * Disable gvfs. This function must be called from main() before
- * starting any threads.
- */
-void
-pv_avoid_gvfs (void)
-{
-  g_autofree gchar *old_env = NULL;
-
-  /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
-  old_env = g_strdup (g_getenv ("GIO_USE_VFS"));
-  g_setenv ("GIO_USE_VFS", "local", TRUE);
-  g_vfs_get_default ();
-  if (old_env)
-    g_setenv ("GIO_USE_VFS", old_env, TRUE);
-  else
-    g_unsetenv ("GIO_USE_VFS");
-}
-
 /**
  * pv_envp_cmp:
  * @p1: a `const char * const *`
diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h
index a30011e09a2c4189e5518be57603cd296b02bf37..4ab9d0a3ae5d048ca60c67433d5fceb2c0344049 100644
--- a/pressure-vessel/utils.h
+++ b/pressure-vessel/utils.h
@@ -35,8 +35,6 @@
 #define PR_SET_CHILD_SUBREAPER 36
 #endif
 
-void pv_avoid_gvfs (void);
-
 int pv_envp_cmp (const void *p1,
                  const void *p2);
 
diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c
index f44fb686900261b7e9e89411a7246a4a1ecdd52d..ea119dad867ec744e974fd2150867958206c6d3e 100644
--- a/pressure-vessel/wrap.c
+++ b/pressure-vessel/wrap.c
@@ -1340,7 +1340,7 @@ main (int argc,
       goto out;
     }
 
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   if (argc < 2 && !opt_test && !opt_only_prepare)
     {
diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h
index dcf62858d0f180709598d02e59eda9fc99df3651..3609b4b888b1a59be2734f4fda56ea2232f134e5 100644
--- a/steam-runtime-tools/utils-internal.h
+++ b/steam-runtime-tools/utils-internal.h
@@ -49,8 +49,7 @@ G_GNUC_INTERNAL GPtrArray *_srt_get_helper (const char *helpers_path,
                                             const char *base,
                                             SrtHelperFlags flags,
                                             GError **error);
-_SRT_PRIVATE_EXPORT
-gchar *_srt_filter_gameoverlayrenderer (const gchar *input);
+G_GNUC_INTERNAL gchar *_srt_filter_gameoverlayrenderer (const gchar *input);
 G_GNUC_INTERNAL const char *_srt_find_myself (const char **helpers_path_out,
                                               GError **error);
 
@@ -111,3 +110,5 @@ gboolean _srt_file_test_in_sysroot (const char *sysroot,
                                     GFileTest test);
 
 G_GNUC_INTERNAL const char * const *_srt_peek_environ_nonnull (void);
+
+G_GNUC_INTERNAL void _srt_setenv_disable_gio_modules (void);
diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c
index ee69aa63fe7c9d6ab82d2df9c7169b4898a7c440..a52f07947597aeb20efa87b3dc3fa024715be6a9 100644
--- a/steam-runtime-tools/utils.c
+++ b/steam-runtime-tools/utils.c
@@ -154,6 +154,8 @@ _srt_check_not_setuid (void)
   "/lib/" _SRT_MULTIARCH
 #define RELOCATABLE_PKGLIBDIR \
   MULTIARCH_LIBDIR "/steam-runtime-tools-" _SRT_API_MAJOR
+#define PKGLIBEXECDIR \
+  "/libexec/steam-runtime-tools-" _SRT_API_MAJOR
 
 /**
  * _srt_process_timeout_wait_status:
@@ -234,17 +236,41 @@ _srt_find_myself (const char **helpers_path_out,
       goto out;
     }
 
-  g_debug ("Found _srt_find_myself() in %s", map->l_name);
-  dir = g_path_get_dirname (map->l_name);
+  if (map->l_name == NULL || map->l_name[0] == '\0')
+    {
+      char *exe = realpath ("/proc/self/exe", NULL);
+
+      if (exe == NULL)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "Unable to locate main executable");
+          goto out;
+        }
+
+      g_debug ("Found _srt_find_myself() in main executable %s", exe);
+      dir = g_path_get_dirname (exe);
+      free (exe);
+    }
+  else
+    {
+      g_debug ("Found _srt_find_myself() in %s", map->l_name);
+      dir = g_path_get_dirname (map->l_name);
+    }
 
   if (g_str_has_suffix (dir, RELOCATABLE_PKGLIBDIR))
     dir[strlen (dir) - strlen (RELOCATABLE_PKGLIBDIR)] = '\0';
   else if (g_str_has_suffix (dir, MULTIARCH_LIBDIR))
     dir[strlen (dir) - strlen (MULTIARCH_LIBDIR)] = '\0';
+  else if (g_str_has_suffix (dir, PKGLIBEXECDIR))
+    dir[strlen (dir) - strlen (PKGLIBEXECDIR)] = '\0';
+  else if (g_str_has_suffix (dir, "/libexec"))
+    dir[strlen (dir) - strlen ("/libexec")] = '\0';
   else if (g_str_has_suffix (dir, "/lib64"))
     dir[strlen (dir) - strlen ("/lib64")] = '\0';
   else if (g_str_has_suffix (dir, "/lib"))
     dir[strlen (dir) - strlen ("/lib")] = '\0';
+  else if (g_str_has_suffix (dir, "/bin"))
+    dir[strlen (dir) - strlen ("/bin")] = '\0';
 
   /* If the library was found in /lib/MULTIARCH, /lib64 or /lib on a
    * merged-/usr system, assume --prefix=/usr (/libexec doesn't
@@ -1014,3 +1040,21 @@ _srt_peek_environ_nonnull (void)
   else
     return no_strings;
 }
+
+/*
+ * Globally disable GIO modules.
+ *
+ * This function modifies the environment, therefore:
+ *
+ * - it must be called from main() before starting any threads
+ * - you must save a copy of the original environment first if you intend
+ *   for subprocesses to receive the original, unmodified environment
+ *
+ * To be effective, it must also be called before any use of GIO APIs.
+ */
+void
+_srt_setenv_disable_gio_modules (void)
+{
+  g_setenv ("GIO_USE_VFS", "local", TRUE);
+  g_setenv ("GIO_MODULE_DIR", "/nonexistent", TRUE);
+}
diff --git a/tests/find-myself.c b/tests/find-myself.c
new file mode 100644
index 0000000000000000000000000000000000000000..bcab0fda281b6e97ab96fb0658594167617c6e9d
--- /dev/null
+++ b/tests/find-myself.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2020 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <steam-runtime-tools/steam-runtime-tools.h>
+
+#include <glib.h>
+
+#include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
+
+/*
+ * Usage: copy the compiled executable into some random prefix and
+ * run it.
+ *
+ * If you put it in /prefix/bin, /prefix/libexec or
+ * /prefix/libexec/steam-runtime-tools-0, it should say that its prefix
+ * is /prefix.
+ */
+
+int
+main (int argc,
+      char **argv)
+{
+  g_autoptr(GError) error = NULL;
+  const char *helpers = NULL;
+  const char *prefix = _srt_find_myself (&helpers, &error);
+
+  if (prefix == NULL)
+    {
+      g_warning ("Unable to find myself: %s", error->message);
+      return 1;
+    }
+
+  g_print ("Prefix: %s\n", prefix);
+  g_print ("Looking for helpers in: %s\n", helpers);
+  return 0;
+}
diff --git a/tests/meson.build b/tests/meson.build
index fbae1660f7930b117c52d7ca0acfb55cf769fb42..bc04ff99677b9b92aecec8ffc2be4b3ac5bf2e09 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -28,19 +28,19 @@ test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'he
 test_env.prepend('PATH', join_paths(meson.current_build_dir(), '..', 'bin'))
 
 tests = [
-  'architecture',
-  'desktop-entry',
-  'graphics',
-  'library',
-  'locale',
-  'system-info',
-  'utils',
+  {'name': 'architecture'},
+  {'name': 'desktop-entry'},
+  {'name': 'graphics'},
+  {'name': 'library'},
+  {'name': 'locale'},
+  {'name': 'system-info'},
+  {'name': 'utils', 'static': true},
 ]
 
 if get_option('bin')
   tests += [
-    'check-requirements-cli',
-    'system-info-cli',
+    {'name': 'check-requirements-cli'},
+    {'name': 'system-info-cli'},
   ]
 endif
 
@@ -56,7 +56,6 @@ test_utils = static_library(
     gio_unix,
     json_glib,
     libglnx_dep,
-    libsteamrt_dep,
   ],
   include_directories : project_include_dirs,
   install: false,
@@ -72,6 +71,17 @@ test_utils_dep = declare_dependency(
   ],
   link_with : test_utils,
 )
+test_utils_static_libsteamrt_dep = declare_dependency(
+  dependencies : [
+    glib,
+    gobject,
+    gio_unix,
+    json_glib,
+    libglnx_dep,
+    libsteamrt_static_dep,
+  ],
+  link_with : test_utils,
+)
 
 tests_dir = join_paths(
   get_option('libexecdir'),
@@ -131,7 +141,15 @@ executable(
   install_dir : tests_dir,
 )
 
-foreach test_name : tests
+foreach test_info : tests
+  test_name = test_info['name']
+
+  if test_info.get('static', false)
+    deps = [libsteamrt_static_dep, test_utils_static_libsteamrt_dep]
+  else
+    deps = [libsteamrt_dep, test_utils_dep]
+  endif
+
   exe = executable(
     'test-' + test_name,
     files(test_name + '.c'),
@@ -144,9 +162,7 @@ foreach test_name : tests
       gio_unix,
       json_glib,
       libglnx_dep,
-      libsteamrt_dep,
-      test_utils_dep,
-    ],
+    ] + deps,
     include_directories : project_include_dirs,
     install : get_option('installed_tests'),
     install_dir : tests_dir,
@@ -171,6 +187,31 @@ foreach test_name : tests
   endif
 endforeach
 
+# Helpers and manual tests statically linked to libsteam-r-t
+foreach helper : [
+  'find-myself',
+]
+  executable(
+    helper,
+    files(helper + '.c'),
+    c_args : [
+      '-D_SRT_MULTIARCH="' + multiarch + '"',
+    ],
+    dependencies : [
+      glib,
+      gobject,
+      gio_unix,
+      json_glib,
+      libglnx_dep,
+      libsteamrt_static_dep,
+      test_utils_static_libsteamrt_dep,
+    ],
+    include_directories : project_include_dirs,
+    install : get_option('installed_tests'),
+    install_dir : tests_dir,
+  )
+endforeach
+
 # A mock implementation of check-locale that offers lots of locales
 executable(
   'mock-check-locale',
diff --git a/tests/pressure-vessel/bwrap-lock.c b/tests/pressure-vessel/bwrap-lock.c
index de00281d72cbc63d9b51b3e000fca62de183b5d9..7e3036c1c169caadedcae41ad2a933c615d79199 100644
--- a/tests/pressure-vessel/bwrap-lock.c
+++ b/tests/pressure-vessel/bwrap-lock.c
@@ -29,6 +29,7 @@
 #include <glib/gstdio.h>
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
 #include "libglnx/libglnx.h"
 
 #include "bwrap-lock.h"
@@ -161,7 +162,7 @@ int
 main (int argc,
       char **argv)
 {
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   g_test_init (&argc, &argv, NULL);
   g_test_add ("/locks", Fixture, NULL,
diff --git a/tests/pressure-vessel/cheap-copy.c b/tests/pressure-vessel/cheap-copy.c
index 511d65c841dc078036055631272195f76edccc3b..321ea7675688ed2f568edefb94a3a4cf99bd47c3 100644
--- a/tests/pressure-vessel/cheap-copy.c
+++ b/tests/pressure-vessel/cheap-copy.c
@@ -26,6 +26,7 @@
 #include "libglnx/libglnx.h"
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
 #include "tree-copy.h"
 #include "utils.h"
 
@@ -52,7 +53,7 @@ main (int argc,
   int ret = EX_USAGE;
 
   setlocale (LC_ALL, "");
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   context = g_option_context_new ("SOURCE DEST");
   g_option_context_add_main_entries (context, options, NULL);
diff --git a/tests/pressure-vessel/elf-get-soname.c b/tests/pressure-vessel/elf-get-soname.c
index c7dff85794e580b67a30c6541e6203cc996d89ad..74ff7571c6c806c525313ce7696f55ac9db9ddc6 100644
--- a/tests/pressure-vessel/elf-get-soname.c
+++ b/tests/pressure-vessel/elf-get-soname.c
@@ -26,6 +26,7 @@
 #include "libglnx/libglnx.h"
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
 
 #include "elf-utils.h"
 #include "utils.h"
@@ -46,7 +47,7 @@ main (int argc,
   int i;
 
   setlocale (LC_ALL, "");
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   context = g_option_context_new ("LIBRARY...");
   g_option_context_add_main_entries (context, options, NULL);
diff --git a/tests/pressure-vessel/resolve-in-sysroot.c b/tests/pressure-vessel/resolve-in-sysroot.c
index bade3586d342b48abf63d1188f8a3992e5ada64d..b578399961d2f49bb6e2c7ad90b76a71c042243c 100644
--- a/tests/pressure-vessel/resolve-in-sysroot.c
+++ b/tests/pressure-vessel/resolve-in-sysroot.c
@@ -31,6 +31,7 @@
 
 #include "steam-runtime-tools/glib-backports-internal.h"
 #include "steam-runtime-tools/resolve-in-sysroot-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
 #include "libglnx/libglnx.h"
 
 #include "tests/test-utils.h"
@@ -298,7 +299,7 @@ int
 main (int argc,
       char **argv)
 {
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   g_test_init (&argc, &argv, NULL);
   g_test_add ("/resolve-in-sysroot", Fixture, NULL,
diff --git a/tests/pressure-vessel/utils.c b/tests/pressure-vessel/utils.c
index f400bc7de22bb6ef1466885ead504a42ead9352e..d900b89643b799d51e435957434848dca84b0296 100644
--- a/tests/pressure-vessel/utils.c
+++ b/tests/pressure-vessel/utils.c
@@ -81,28 +81,6 @@ test_arbitrary_key (Fixture *f,
     g_assert_cmpstr (k, ==, "world");
 }
 
-static void
-test_avoid_gvfs (Fixture *f,
-                 gconstpointer context)
-{
-  /* This doesn't actually call pv_avoid_gvfs(), because that's documented
-   * to have to happen as early as possible in main(). Instead, we do that
-   * in main() as documented, and in this function we just assert that
-   * we did. */
-  GVfs *vfs = g_vfs_get_default ();
-  GVfs *local = g_vfs_get_local ();
-
-  g_test_message ("Default VFS: %s at %p", G_OBJECT_TYPE_NAME (vfs), vfs);
-  g_test_message ("Local VFS: %s at %p", G_OBJECT_TYPE_NAME (local), local);
-  /* We compare by string equality to have a better message if this
-   * assertion fails. We can't assert that the pointers are the same,
-   * because GLib currently uses two instances of the same class. */
-  g_assert_cmpstr (G_OBJECT_TYPE_NAME (vfs), ==,
-                   G_OBJECT_TYPE_NAME (local));
-  g_assert_cmpuint (G_OBJECT_TYPE (vfs), ==,
-                    G_OBJECT_TYPE (local));
-}
-
 static void
 test_capture_output (Fixture *f,
                      gconstpointer context)
@@ -279,126 +257,21 @@ test_search_path_append (Fixture *f,
   g_assert_cmpstr (str->str, ==, "/bin:/usr/bin:/usr/bin");
 }
 
-typedef struct
-{
-  const char *name;
-  mode_t mode;
-} File;
-
-typedef struct
-{
-  const char *name;
-  const char *target;
-} Symlink;
-
-typedef struct
-{
-  const char *path;
-  GFileTest test;
-  gboolean expected_result;
-} InSysrootTest;
-
-static void
-test_file_in_sysroot (Fixture *f,
-                      gconstpointer context)
-{
-  static const char * const prepare_dirs[] =
-  {
-    "dir1/dir2/dir3",
-  };
-
-  static const File prepare_files[] =
-  {
-    { "dir1/file1", 0600 },
-    { "dir1/dir2/file2", 0600 },
-    { "dir1/exec1", 0700 },
-  };
-
-  static const Symlink prepare_symlinks[] =
-  {
-    { "dir1/dir2/symlink_to_dir3", "dir3" },
-    { "dir1/dir2/symlink_to_file2", "file2" },
-    { "dir1/dir2/sym_to_sym_to_file2", "symlink_to_file2" },
-    { "dir1/abs_symlink_to_run", "/run" },
-  };
-
-  static const InSysrootTest tests[] =
-  {
-    { "dir1", G_FILE_TEST_IS_DIR, TRUE },
-    { "dir1", G_FILE_TEST_EXISTS, TRUE },
-    { "/dir1", G_FILE_TEST_EXISTS, TRUE },
-    { "dir1/dir2", G_FILE_TEST_IS_DIR, TRUE },
-    /* These gets solved in sysroot, following symlinks too */
-    { "dir1/dir2/symlink_to_dir3", G_FILE_TEST_IS_DIR, TRUE },
-    { "dir1/dir2/sym_to_sym_to_file2", G_FILE_TEST_IS_REGULAR, TRUE },
-    { "dir1/abs_symlink_to_run", G_FILE_TEST_IS_DIR, FALSE },
-    { "dir1/missing", G_FILE_TEST_EXISTS, FALSE },
-    { "dir1/file1", G_FILE_TEST_IS_REGULAR, TRUE },
-    { "dir1/file1", (G_FILE_TEST_IS_DIR | G_FILE_TEST_IS_EXECUTABLE), FALSE },
-    { "dir1/exec1", G_FILE_TEST_IS_REGULAR, TRUE },
-    { "dir1/exec1", G_FILE_TEST_IS_EXECUTABLE, TRUE },
-  };
-
-  g_autoptr(GError) error = NULL;
-  g_auto(GLnxTmpDir) tmpdir = { FALSE };
-  gsize i;
-
-  glnx_mkdtemp ("test-XXXXXX", 0700, &tmpdir, &error);
-  g_assert_no_error (error);
-
-  for (i = 0; i < G_N_ELEMENTS (prepare_dirs); i++)
-    {
-      const char *it = prepare_dirs[i];
-
-      glnx_shutil_mkdir_p_at (tmpdir.fd, it, 0700, NULL, &error);
-      g_assert_no_error (error);
-    }
-
-  for (i = 0; i < G_N_ELEMENTS (prepare_files); i++)
-    {
-      const File *it = &prepare_files[i];
-
-      glnx_autofd int fd = openat (tmpdir.fd, it->name, O_WRONLY|O_CREAT, it->mode);
-      if (fd == -1)
-        g_error ("openat %s: %s", it->name, g_strerror (errno));
-    }
-
-  for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++)
-    {
-      const Symlink *it = &prepare_symlinks[i];
-
-      if (symlinkat (it->target, tmpdir.fd, it->name) != 0)
-        g_error ("symlinkat %s: %s", it->name, g_strerror (errno));
-    }
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    {
-      const InSysrootTest *it = &tests[i];
-
-      g_assert_cmpint (_srt_file_test_in_sysroot (tmpdir.path, -1,
-                                                  it->path, it->test),
-                       ==, it->expected_result);
-    }
-}
-
 int
 main (int argc,
       char **argv)
 {
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   g_test_init (&argc, &argv, NULL);
   g_test_add ("/arbitrary-key", Fixture, NULL,
               setup, test_arbitrary_key, teardown);
-  g_test_add ("/avoid-gvfs", Fixture, NULL, setup, test_avoid_gvfs, teardown);
   g_test_add ("/capture-output", Fixture, NULL,
               setup, test_capture_output, teardown);
   g_test_add ("/envp-cmp", Fixture, NULL, setup, test_envp_cmp, teardown);
   g_test_add ("/same-file", Fixture, NULL, setup, test_same_file, teardown);
   g_test_add ("/search-path-append", Fixture, NULL,
               setup, test_search_path_append, teardown);
-  g_test_add ("/test-file-in-sysroot", Fixture, NULL,
-              setup, test_file_in_sysroot, teardown);
 
   return g_test_run ();
 }
diff --git a/tests/pressure-vessel/wait-for-child-processes.c b/tests/pressure-vessel/wait-for-child-processes.c
index 8faf8e798b28de09ab049bb737a728ea06abe5f8..fa6523cb95fd4373fa5cb4d29ffe3ff7c05f896f 100644
--- a/tests/pressure-vessel/wait-for-child-processes.c
+++ b/tests/pressure-vessel/wait-for-child-processes.c
@@ -34,6 +34,7 @@
 
 #include "steam-runtime-tools/glib-backports-internal.h"
 #include "libglnx/libglnx.h"
+#include "steam-runtime-tools/utils-internal.h"
 
 #include "tests/test-utils.h"
 #include "utils.h"
@@ -323,7 +324,7 @@ main (int argc,
     g_error ("pthread_sigmask: %s", g_strerror (errno));
 
   prctl (PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
-  pv_avoid_gvfs ();
+  _srt_setenv_disable_gio_modules ();
 
   g_test_init (&argc, &argv, NULL);
   g_test_add ("/terminate/nothing", Fixture, NULL,
diff --git a/tests/utils.c b/tests/utils.c
index 2fc3c60c0ed215ad2a0ed16e3baba4746779c35d..25c70547c87fc504dd5ac07d1740d71f57b302e2 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -56,6 +56,131 @@ teardown (Fixture *f,
   G_GNUC_UNUSED const Config *config = context;
 }
 
+static void
+test_avoid_gvfs (Fixture *f,
+                 gconstpointer context)
+{
+  /* This doesn't actually call _srt_setenv_disable_gio_modules(),
+   * because that's documented
+   * to have to happen as early as possible in main(). Instead, we do that
+   * in main() as documented, and in this function we just assert that
+   * we did. */
+  GVfs *vfs = g_vfs_get_default ();
+  GVfs *local = g_vfs_get_local ();
+
+  g_test_message ("Default VFS: %s at %p", G_OBJECT_TYPE_NAME (vfs), vfs);
+  g_test_message ("Local VFS: %s at %p", G_OBJECT_TYPE_NAME (local), local);
+  /* We compare by string equality to have a better message if this
+   * assertion fails. We can't assert that the pointers are the same,
+   * because GLib currently uses two instances of the same class. */
+  g_assert_cmpstr (G_OBJECT_TYPE_NAME (vfs), ==,
+                   G_OBJECT_TYPE_NAME (local));
+  g_assert_cmpuint (G_OBJECT_TYPE (vfs), ==,
+                    G_OBJECT_TYPE (local));
+}
+
+typedef struct
+{
+  const char *name;
+  mode_t mode;
+} File;
+
+typedef struct
+{
+  const char *name;
+  const char *target;
+} Symlink;
+
+typedef struct
+{
+  const char *path;
+  GFileTest test;
+  gboolean expected_result;
+} InSysrootTest;
+
+static void
+test_file_in_sysroot (Fixture *f,
+                      gconstpointer context)
+{
+  static const char * const prepare_dirs[] =
+  {
+    "dir1/dir2/dir3",
+  };
+
+  static const File prepare_files[] =
+  {
+    { "dir1/file1", 0600 },
+    { "dir1/dir2/file2", 0600 },
+    { "dir1/exec1", 0700 },
+  };
+
+  static const Symlink prepare_symlinks[] =
+  {
+    { "dir1/dir2/symlink_to_dir3", "dir3" },
+    { "dir1/dir2/symlink_to_file2", "file2" },
+    { "dir1/dir2/sym_to_sym_to_file2", "symlink_to_file2" },
+    { "dir1/abs_symlink_to_run", "/run" },
+  };
+
+  static const InSysrootTest tests[] =
+  {
+    { "dir1", G_FILE_TEST_IS_DIR, TRUE },
+    { "dir1", G_FILE_TEST_EXISTS, TRUE },
+    { "/dir1", G_FILE_TEST_EXISTS, TRUE },
+    { "dir1/dir2", G_FILE_TEST_IS_DIR, TRUE },
+    /* These gets solved in sysroot, following symlinks too */
+    { "dir1/dir2/symlink_to_dir3", G_FILE_TEST_IS_DIR, TRUE },
+    { "dir1/dir2/sym_to_sym_to_file2", G_FILE_TEST_IS_REGULAR, TRUE },
+    { "dir1/abs_symlink_to_run", G_FILE_TEST_IS_DIR, FALSE },
+    { "dir1/missing", G_FILE_TEST_EXISTS, FALSE },
+    { "dir1/file1", G_FILE_TEST_IS_REGULAR, TRUE },
+    { "dir1/file1", (G_FILE_TEST_IS_DIR | G_FILE_TEST_IS_EXECUTABLE), FALSE },
+    { "dir1/exec1", G_FILE_TEST_IS_REGULAR, TRUE },
+    { "dir1/exec1", G_FILE_TEST_IS_EXECUTABLE, TRUE },
+  };
+
+  g_autoptr(GError) error = NULL;
+  g_auto(GLnxTmpDir) tmpdir = { FALSE };
+  gsize i;
+
+  glnx_mkdtemp ("test-XXXXXX", 0700, &tmpdir, &error);
+  g_assert_no_error (error);
+
+  for (i = 0; i < G_N_ELEMENTS (prepare_dirs); i++)
+    {
+      const char *it = prepare_dirs[i];
+
+      glnx_shutil_mkdir_p_at (tmpdir.fd, it, 0700, NULL, &error);
+      g_assert_no_error (error);
+    }
+
+  for (i = 0; i < G_N_ELEMENTS (prepare_files); i++)
+    {
+      const File *it = &prepare_files[i];
+
+      glnx_autofd int fd = openat (tmpdir.fd, it->name, O_WRONLY|O_CREAT, it->mode);
+      if (fd == -1)
+        g_error ("openat %s: %s", it->name, g_strerror (errno));
+    }
+
+  for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++)
+    {
+      const Symlink *it = &prepare_symlinks[i];
+
+      if (symlinkat (it->target, tmpdir.fd, it->name) != 0)
+        g_error ("symlinkat %s: %s", it->name, g_strerror (errno));
+    }
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    {
+      const InSysrootTest *it = &tests[i];
+
+      g_assert_cmpint (_srt_file_test_in_sysroot (tmpdir.path, -1,
+                                                  it->path, it->test),
+                       ==, it->expected_result);
+    }
+}
+
 /*
  * Test _srt_filter_gameoverlayrenderer function.
  */
@@ -95,7 +220,12 @@ int
 main (int argc,
       char **argv)
 {
+  _srt_setenv_disable_gio_modules ();
+
   g_test_init (&argc, &argv, NULL);
+  g_test_add ("/utils/avoid-gvfs", Fixture, NULL, setup, test_avoid_gvfs, teardown);
+  g_test_add ("/utils/test-file-in-sysroot", Fixture, NULL,
+              setup, test_file_in_sysroot, teardown);
   g_test_add ("/utils/filter_gameoverlayrenderer", Fixture, NULL, setup,
               filter_gameoverlayrenderer, teardown);