diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index dd0047082468..941f820d944c 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -547,18 +547,6 @@ elf_crc32_file (struct backtrace_state *state, int descriptor,
   return ret;
 }
 
-/* A dummy callback function used when we can't find any debug info.  */
-
-static int
-elf_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
-	     uintptr_t pc ATTRIBUTE_UNUSED,
-	     backtrace_full_callback callback ATTRIBUTE_UNUSED,
-	     backtrace_error_callback error_callback, void *data)
-{
-  error_callback (data, "no debug info in ELF executable", -1);
-  return 0;
-}
-
 /* A dummy callback function used when we can't find a symbol
    table.  */
 
@@ -571,6 +559,33 @@ elf_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
   error_callback (data, "no symbol table in ELF executable", -1);
 }
 
+/* A callback function used when we can't find any debug info.  */
+
+static int
+elf_nodebug (struct backtrace_state *state, uintptr_t pc,
+	     backtrace_full_callback callback,
+	     backtrace_error_callback error_callback, void *data)
+{
+  if (state->syminfo_fn != NULL && state->syminfo_fn != elf_nosyms)
+    {
+      struct backtrace_call_full bdata;
+
+      /* Fetch symbol information so that we can least get the
+	 function name.  */
+
+      bdata.full_callback = callback;
+      bdata.full_error_callback = error_callback;
+      bdata.full_data = data;
+      bdata.ret = 0;
+      state->syminfo_fn (state, pc, backtrace_syminfo_to_full_callback,
+			 backtrace_syminfo_to_full_error_callback, &bdata);
+      return bdata.ret;
+    }
+
+  error_callback (data, "no debug info in ELF executable", -1);
+  return 0;
+}
+
 /* Compare struct elf_symbol for qsort.  */
 
 static int
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index be62b9899c5a..cd1e10dd58cc 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -317,3 +317,30 @@ backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
   state->syminfo_fn (state, pc, callback, error_callback, data);
   return 1;
 }
+
+/* A backtrace_syminfo_callback that can call into a
+   backtrace_full_callback, used when we have a symbol table but no
+   debug info.  */
+
+void
+backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
+				    const char *symname,
+				    uintptr_t symval ATTRIBUTE_UNUSED,
+				    uintptr_t symsize ATTRIBUTE_UNUSED)
+{
+  struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
+
+  bdata->ret = bdata->full_callback (bdata->full_data, pc, NULL, 0, symname);
+}
+
+/* An error callback that corresponds to
+   backtrace_syminfo_to_full_callback.  */
+
+void
+backtrace_syminfo_to_full_error_callback (void *data, const char *msg,
+					  int errnum)
+{
+  struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
+
+  bdata->full_error_callback (bdata->full_data, msg, errnum);
+}
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index 098623374560..047a700c0ce4 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -326,6 +326,31 @@ extern int backtrace_dwarf_add (struct backtrace_state *state,
 				void *data, fileline *fileline_fn,
 				struct dwarf_data **fileline_entry);
 
+/* A data structure to pass to backtrace_syminfo_to_full.  */
+
+struct backtrace_call_full
+{
+  backtrace_full_callback full_callback;
+  backtrace_error_callback full_error_callback;
+  void *full_data;
+  int ret;
+};
+
+/* A backtrace_syminfo_callback that can call into a
+   backtrace_full_callback, used when we have a symbol table but no
+   debug info.  */
+
+extern void backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
+						const char *symname,
+						uintptr_t symval,
+						uintptr_t symsize);
+
+/* An error callback that corresponds to
+   backtrace_syminfo_to_full_callback.  */
+
+extern void backtrace_syminfo_to_full_error_callback (void *, const char *,
+						      int);
+
 /* A test-only hook for elf_uncompress_zdebug.  */
 
 extern int backtrace_uncompress_zdebug (struct backtrace_state *,
diff --git a/libbacktrace/mtest.c b/libbacktrace/mtest.c
index d90fd1e33cc3..d73c98d44f8e 100644
--- a/libbacktrace/mtest.c
+++ b/libbacktrace/mtest.c
@@ -156,40 +156,49 @@ f3 (int f1line __attribute__ ((unused)), int f2line __attribute__ ((unused)))
 	}
     }
 
-  if (all[0].function == NULL)
+  if (data.index > 0)
     {
-      fprintf (stderr, "test1: [0]: missing function name\n");
-      data.failed = 1;
-    }
-  else if (strcmp (all[0].function, "f3") != 0)
-    {
-      fprintf (stderr, "test1: [0]: got %s expected %s\n",
-	       all[0].function, "f3");
-      data.failed = 1;
+      if (all[0].function == NULL)
+	{
+	  fprintf (stderr, "test1: [0]: missing function name\n");
+	  data.failed = 1;
+	}
+      else if (strcmp (all[0].function, "f3") != 0)
+	{
+	  fprintf (stderr, "test1: [0]: got %s expected %s\n",
+		   all[0].function, "f3");
+	  data.failed = 1;
+	}
     }
 
-  if (all[1].function == NULL)
+  if (data.index > 1)
     {
-      fprintf (stderr, "test1: [1]: missing function name\n");
-      data.failed = 1;
-    }
-  else if (strcmp (all[1].function, "f2") != 0)
-    {
-      fprintf (stderr, "test1: [1]: got %s expected %s\n",
-	       all[0].function, "f2");
-      data.failed = 1;
+      if (all[1].function == NULL)
+	{
+	  fprintf (stderr, "test1: [1]: missing function name\n");
+	  data.failed = 1;
+	}
+      else if (strcmp (all[1].function, "f2") != 0)
+	{
+	  fprintf (stderr, "test1: [1]: got %s expected %s\n",
+		   all[0].function, "f2");
+	  data.failed = 1;
+	}
     }
 
-  if (all[2].function == NULL)
+  if (data.index > 2)
     {
-      fprintf (stderr, "test1: [2]: missing function name\n");
-      data.failed = 1;
-    }
-  else if (strcmp (all[2].function, "test1") != 0)
-    {
-      fprintf (stderr, "test1: [2]: got %s expected %s\n",
-	       all[0].function, "test1");
-      data.failed = 1;
+      if (all[2].function == NULL)
+	{
+	  fprintf (stderr, "test1: [2]: missing function name\n");
+	  data.failed = 1;
+	}
+      else if (strcmp (all[2].function, "test1") != 0)
+	{
+	  fprintf (stderr, "test1: [2]: got %s expected %s\n",
+		   all[0].function, "test1");
+	  data.failed = 1;
+	}
     }
 
   printf ("%s: backtrace_full noinline\n", data.failed ? "FAIL" : "PASS");