diff --git a/steam-runtime-tools/library.c b/steam-runtime-tools/library.c
index 0949a6e17eb9964e2c1e420053ecefd52c75a89a..681d4bb98980d5d035d12aa7dfc6f69cf564ebf1 100644
--- a/steam-runtime-tools/library.c
+++ b/steam-runtime-tools/library.c
@@ -27,6 +27,7 @@
 
 #include "steam-runtime-tools/architecture.h"
 #include "steam-runtime-tools/enums.h"
+#include "steam-runtime-tools/glib-compat.h"
 #include "steam-runtime-tools/library-internal.h"
 #include "steam-runtime-tools/utils.h"
 #include "steam-runtime-tools/utils-internal.h"
@@ -506,7 +507,6 @@ _srt_check_library_presence (const char *helpers_path,
   GStrv my_environ = NULL;
   const gchar *ld_preload;
   gchar *filtered_preload = NULL;
-  argv = g_ptr_array_new_with_free_func (g_free);
 
   g_return_val_if_fail (soname != NULL, SRT_LIBRARY_ISSUES_INTERNAL_ERROR);
   g_return_val_if_fail (multiarch != NULL, SRT_LIBRARY_ISSUES_INTERNAL_ERROR);
@@ -517,10 +517,10 @@ _srt_check_library_presence (const char *helpers_path,
   if (symbols_path == NULL)
     issues |= SRT_LIBRARY_ISSUES_UNKNOWN_EXPECTATIONS;
 
-  if (helpers_path == NULL)
-    helpers_path = _srt_get_helpers_path (&error);
+  argv = _srt_get_helper (helpers_path, multiarch, "inspect-library",
+                          SRT_HELPER_FLAGS_NONE, &error);
 
-  if (helpers_path == NULL)
+  if (argv == NULL)
     {
       issues |= SRT_LIBRARY_ISSUES_CANNOT_LOAD;
       /* Use the error message as though the child had printed it on stderr -
@@ -529,7 +529,6 @@ _srt_check_library_presence (const char *helpers_path,
       goto out;
     }
 
-  g_ptr_array_add (argv, g_strdup_printf ("%s/%s-inspect-library", helpers_path, multiarch));
   g_debug ("Checking library %s integrity with %s", soname, (gchar *)g_ptr_array_index (argv, 0));
 
   switch (symbols_format)
@@ -674,7 +673,7 @@ out:
   g_strfreev (missing_symbols);
   g_strfreev (misversioned_symbols);
   g_strfreev (dependencies);
-  g_ptr_array_free (argv, TRUE);
+  g_clear_pointer (&argv, g_ptr_array_unref);
   g_free (absolute_path);
   g_free (child_stderr);
   g_free (output);
diff --git a/steam-runtime-tools/locale.c b/steam-runtime-tools/locale.c
index 9fbcb050969197b4180c07da8c4feae70ccdf020..a59e08d8568b675892f4bd9f18bbb071373fde3c 100644
--- a/steam-runtime-tools/locale.c
+++ b/steam-runtime-tools/locale.c
@@ -225,10 +225,13 @@ _srt_check_locale (const char *helpers_path,
   g_return_val_if_fail (requested_name != NULL, NULL);
   g_return_val_if_fail (_srt_check_not_setuid (), NULL);
 
-  if (helpers_path == NULL)
-    helpers_path = _srt_get_helpers_path (error);
+  if (multiarch_tuple == NULL)
+    multiarch_tuple = _SRT_MULTIARCH;
 
-  if (helpers_path == NULL)
+  argv = _srt_get_helper (helpers_path, multiarch_tuple, "check-locale",
+                          SRT_HELPER_FLAGS_NONE, error);
+
+  if (argv == NULL)
     goto out;
 
   my_environ = g_get_environ ();
@@ -240,13 +243,6 @@ _srt_check_locale (const char *helpers_path,
                                      filtered_preload, TRUE);
     }
 
-  argv = g_ptr_array_new_with_free_func (g_free);
-
-  if (multiarch_tuple == NULL)
-    multiarch_tuple = _SRT_MULTIARCH;
-
-  g_ptr_array_add (argv, g_strdup_printf ("%s/%s-check-locale",
-                                          helpers_path, multiarch_tuple));
   g_ptr_array_add (argv, g_strdup (requested_name));
 
   g_ptr_array_add (argv, NULL);
@@ -353,7 +349,7 @@ out:
     }
 
   g_clear_object (&parser);
-  g_ptr_array_unref (argv);
+  g_clear_pointer (&argv, g_ptr_array_unref);
   g_free (output);
   g_free (filtered_preload);
   g_strfreev (my_environ);
diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h
index f246351367d793c0182b22c41fd01b964330c6ef..bac38725eac9339f3896194400a25e1126f1b71d 100644
--- a/steam-runtime-tools/utils-internal.h
+++ b/steam-runtime-tools/utils-internal.h
@@ -28,5 +28,15 @@
 
 #include <glib.h>
 
+typedef enum
+{
+  SRT_HELPER_FLAGS_NONE = 0
+} SrtHelperFlags;
+
+G_GNUC_INTERNAL GPtrArray *_srt_get_helper (const char *helpers_path,
+                                            const char *multiarch,
+                                            const char *base,
+                                            SrtHelperFlags flags,
+                                            GError **error);
 G_GNUC_INTERNAL const char *_srt_get_helpers_path (GError **error);
 gchar *_srt_filter_gameoverlayrenderer (const gchar *input);
diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c
index 8a7057580973d45470ea50a27c1f458bbfc698cf..3908dd4f920bd1e40497bcc9f9bcb3c9038bc728 100644
--- a/steam-runtime-tools/utils.c
+++ b/steam-runtime-tools/utils.c
@@ -40,6 +40,7 @@
 
 #include <glib-object.h>
 #include <gio/gio.h>
+#include "steam-runtime-tools/glib-compat.h"
 
 #ifdef HAVE_GETAUXVAL
 #define getauxval_AT_SECURE() getauxval (AT_SECURE)
@@ -209,6 +210,73 @@ out:
   return path;
 }
 
+/*
+ * _srt_get_helper:
+ * @helpers_path: (nullable): Directory to search for helper executables,
+ *  or %NULL for default behaviour
+ * @multiarch: (nullable): A multiarch tuple like %SRT_ABI_I386 to prefix
+ *  to the executable name, or %NULL
+ * @base: (not nullable): Base name of the executable
+ * @flags: Flags affecting how we set up the helper
+ * @error: Used to raise an error if %NULL is returned
+ *
+ * Find a helper executable. We return an array of arguments so that the
+ * helper can be wrapped by an "adverb" like `env`, `timeout` or a
+ * specific `ld.so` implementation if required.
+ *
+ * Returns: (nullable) (element-type filename) (transfer container): The
+ *  initial `argv` for the helper, with g_free() set as the free-function, and
+ *  no %NULL terminator. Free with g_ptr_array_unref() or g_ptr_array_free().
+ */
+G_GNUC_INTERNAL GPtrArray *
+_srt_get_helper (const char *helpers_path,
+                 const char *multiarch,
+                 const char *base,
+                 SrtHelperFlags flags,
+                 GError **error)
+{
+  GPtrArray *argv = NULL;
+  gchar *path;
+
+  g_return_val_if_fail (base != NULL, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  argv = g_ptr_array_new_with_free_func (g_free);
+
+  if (helpers_path == NULL)
+    {
+      helpers_path = _srt_get_helpers_path (error);
+
+      if (helpers_path == NULL)
+        {
+          g_ptr_array_unref (argv);
+          return NULL;
+        }
+    }
+
+  path = g_strdup_printf ("%s/%s%s%s",
+                          helpers_path,
+                          multiarch == NULL ? "" : multiarch,
+                          multiarch == NULL ? "" : "-",
+                          base);
+
+  g_debug ("Looking for %s", path);
+
+  if (g_file_test (path, G_FILE_TEST_IS_EXECUTABLE))
+    {
+      g_ptr_array_add (argv, g_steal_pointer (&path));
+      return argv;
+    }
+  else
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                   "%s not found", path);
+      g_free (path);
+      g_ptr_array_unref (argv);
+      return NULL;
+    }
+}
+
 /**
  * _srt_filter_gameoverlayrenderer:
  * @input: The environment variable value that needs to be filtered.