diff --git a/tests/utils.c b/tests/utils.c
index 0f10e7743c41cb7efb568c1e220e25097e05a918..c0540b873524e5f1c33cee11500bcb32e0503667 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -134,6 +134,48 @@ test_build_filename (Fixture *f,
     }
 }
 
+static void
+test_ptr_list (Fixture *f,
+               gconstpointer data)
+{
+  size_t n;
+  ptr_list *list;
+  void **array;
+
+  list = ptr_list_alloc (0);
+  ptr_list_push_ptr (list, (char *) "hello");
+  ptr_list_add_ptr (list, (char *) "world", g_str_equal);
+  ptr_list_add_ptr (list, (char *) "hello", g_str_equal);    // duplicate, not added
+  ptr_list_add_ptr (list, (char *) "world", g_str_equal);    // duplicate, not added
+  ptr_list_push_ptr (list, (char *) "hello");
+  ptr_list_push_ptr (list, NULL);
+  ptr_list_push_addr (list, 23);
+
+  g_assert_cmpstr (ptr_list_nth_ptr (list, 0), ==, "hello");
+  g_assert_cmpstr (ptr_list_nth_ptr (list, 1), ==, "world");
+  g_assert_cmpstr (ptr_list_nth_ptr (list, 2), ==, "hello");
+  g_assert_cmpstr (ptr_list_nth_ptr (list, 3), ==, NULL);
+  g_assert_cmpuint (GPOINTER_TO_SIZE (ptr_list_nth_ptr (list, 4)), ==, 23);
+  g_assert_cmpstr (ptr_list_nth_ptr (list, 5), ==, NULL);
+  g_assert_cmpstr (ptr_list_nth_ptr (list, 47), ==, NULL);
+  g_assert_true (ptr_list_contains (list, 23));
+  g_assert_true (ptr_list_contains (list, (ElfW(Addr)) ptr_list_nth_ptr (list, 1)));
+  g_assert_false (ptr_list_contains (list, 1));
+
+  array = ptr_list_free_to_array (list, &n);
+  g_assert_cmpint (n, ==, 5);
+  g_assert_cmpstr (array[0], ==, "hello");
+  g_assert_cmpstr (array[1], ==, "world");
+  g_assert_cmpstr (array[2], ==, "hello");
+  g_assert_cmpstr (array[3], ==, NULL);
+  g_assert_cmpuint (GPOINTER_TO_SIZE (array[4]), ==, 23);
+  g_assert_cmpstr (array[5], ==, NULL);
+  free (array);
+
+  list = ptr_list_alloc (0);
+  ptr_list_free (list);
+}
+
 static void
 teardown (Fixture *f,
           gconstpointer data)
@@ -149,6 +191,7 @@ main (int argc,
 
   g_test_add ("/build-filename", Fixture, NULL, setup,
               test_build_filename, teardown);
+  g_test_add ("/ptr-list", Fixture, NULL, setup, test_ptr_list, teardown);
 
   return g_test_run ();
 }
diff --git a/utils/utils.c b/utils/utils.c
index dd70f197b4fe086b2ed2e287a3c482c5dcb27b94..7da3b69be3252b4d38065f5d9189e7a1f475afe2 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -462,6 +462,41 @@ ptr_list_alloc(size_t size)
     return list;
 }
 
+/*
+ * ptr_list_free_to_array:
+ * @list: (transfer full): list to free
+ * @n: (out) (optional): if not %NULL, used to return the number of
+ *  items that were in @list
+ *
+ * Add an extra %NULL entry to @list, then return an array with the
+ * same contents as @list, freeing @list. If @n is not %NULL, set it
+ * to the number of elements in the returned array before the %NULL
+ * added by this function.
+ */
+void **
+ptr_list_free_to_array (ptr_list *list, size_t *n)
+{
+    void *ret;
+
+    // Without these assertions, it's unsafe to assign a ptr_item *
+    // to a void **
+    static_assert( alignof( void * ) == alignof( ptr_item ),
+                   "union {void *, ElfW(Addr)} assumed to be same size "
+                   "as void *");
+    static_assert( sizeof( void * ) == sizeof( ptr_item ),
+                   "union {void *, ElfW(Addr)} assumed to be same "
+                   "alignment as void *");
+
+    if( n != NULL )
+        *n = list->next;
+
+    ptr_list_push_ptr( list, NULL );
+    ret = list->loc;
+    list->loc = NULL;
+    ptr_list_free (list);
+    return ret;
+}
+
 void
 ptr_list_free (ptr_list *list)
 {
diff --git a/utils/utils.h b/utils/utils.h
index 89aee28f5ba9b034cda5076995bbd34c9c027113..e14af8665efef8c66dc3f551655e69ed7bbb94ad 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -75,6 +75,7 @@ typedef int (*ptrcmp) (const void *a, const void *b);
 ptr_list *ptr_list_alloc (size_t size);
 void *ptr_list_nth_ptr (ptr_list *list, size_t nth);
 void ptr_list_free (ptr_list *list);
+void **ptr_list_free_to_array (ptr_list *list, size_t *n);
 void ptr_list_push_ptr  (ptr_list *list, void *ptr);
 void ptr_list_push_addr (ptr_list *list, ElfW(Addr) addr);
 int  ptr_list_contains  (ptr_list *list, ElfW(Addr) addr);