commit a2c27a4ab724cf129cf956df4c6fb779bd2f5366
Author: Arun Sharma <aruns@google.com>
Date:   Mon Mar 16 21:21:58 2009 -0700

    Make .debug_frame support optional.
    
    Because these code paths use malloc and stdio, they could
    cause deadlocks when we try to unwind stack from inside malloc.

diff --git a/configure.in b/configure.in
index 7f7aef8..789613d 100644
--- a/configure.in
+++ b/configure.in
@@ -124,6 +124,10 @@ if test x$enable_cxx_exceptions = xyes; then
 fi
 AM_CONDITIONAL([SUPPORT_CXX_EXCEPTIONS], [test x$enable_cxx_exceptions = xyes])
 
+AC_ARG_ENABLE(debug_frame,
+[  --enable-debug-frame Load the ".debug_frame" section if available],
+[enable_debug_frame=$enableval], [enable_debug_frame=yes])
+AM_CONDITIONAL([CONFIG_DEBUG_FRAME], [test x$enable_debug_frame = xyes])
 LIBUNWIND___THREAD
 
 save_LDFLAGS="$LDFLAGS"
diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c
index d3d5fe5..e2fd4fe 100644
--- a/src/dwarf/Gfind_proc_info-lsb.c
+++ b/src/dwarf/Gfind_proc_info-lsb.c
@@ -92,6 +92,7 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
   return -UNW_ENOINFO;
 }
 
+#ifdef CONFIG_DEBUG_FRAME
 /* Load .debug_frame section from FILE.  Allocates and returns space
    in *BUF, and sets *BUFSIZE to its size.  IS_LOCAL is 1 if using the
    local process, in which case we can search the system debug file
@@ -132,7 +133,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
   sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr)));
   fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f);
   
-  Debug (4, "loading string table of size %d\n",
+  Debug (4, "loading string table of size %zd\n",
 	   sec_hdrs[shstrndx].sh_size);
   stringtab = malloc (sec_hdrs[shstrndx].sh_size);
   fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET);
@@ -150,7 +151,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
 	  fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
 	  fread (*buf, 1, *bufsize, f);
 
-	  Debug (4, "read %d bytes of .debug_frame from offset %d\n",
+	  Debug (4, "read %zd bytes of .debug_frame from offset %zd\n",
 		 *bufsize, sec_hdrs[i].sh_offset);
 	}
       else if (is_local >= 0 && strcmp (secname, ".gnu_debuglink") == 0)
@@ -161,7 +162,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
 	  fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
 	  fread (linkbuf, 1, linksize, f);
 
-	  Debug (4, "read %d bytes of .gnu_debuglink from offset %d\n",
+	  Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n",
 		 *bufsize, sec_hdrs[i].sh_offset);
 	}
     }
@@ -220,36 +221,37 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
 
   return 0;
 }
+#else
+static int
+load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
+{
+  return 1;
+}
+#endif /* CONFIG_DEBUG_FRAME */
+
 
 /* Locate the binary which originated the contents of address ADDR. Return
-   the name of the binary in *name (which is allocated on the heap, and must
-   be freed by the caller).  Returns 0 if a binary is successfully found, or 1
-   if an error occurs.  */
+   the name of the binary in *name (space is allocated by the caller)
+   Returns 0 if a binary is successfully found, or 1 if an error occurs.  */
 
 static int
-find_binary_for_address (unw_word_t ip, char **name)
+find_binary_for_address (unw_word_t ip, char *name, size_t name_size)
 {
 #ifdef __linux
   struct map_iterator mi;
-  char path[PATH_MAX];
   int found = 0;
   int pid = getpid ();
   unsigned long segbase, mapoff, hi;
 
   maps_init (&mi, pid);
-  while (maps_next (&mi, &segbase, &hi, &mapoff, path, sizeof (path)))
+  while (maps_next (&mi, &segbase, &hi, &mapoff, name, name_size))
     if (ip >= segbase && ip < hi)
       {
 	found = 1;
 	break;
       }
   maps_close (&mi);
-
-  if (found)
-    {
-      *name = strdup (path);
-      return 0;
-    }
+  return ~found;
 #endif
 
   return 1;
@@ -263,7 +265,8 @@ locate_debug_info (unw_addr_space_t as, struct dl_phdr_info *info,
 		   unw_word_t addr, const char *dlname)
 {
   struct unw_debug_frame_list *w, *fdesc = 0;
-  char *name = 0;
+  char path[PATH_MAX];
+  char *name = path;
   int err;
   uint64_t start = 0, end = 0;
   char *buf;
@@ -284,7 +287,7 @@ locate_debug_info (unw_addr_space_t as, struct dl_phdr_info *info,
 
   if (strcmp (dlname, "") == 0)
     {
-      err = find_binary_for_address (addr, &name);
+      err = find_binary_for_address (addr, name, sizeof(path));
       if (err)
         {
 	  Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n",
@@ -334,9 +337,6 @@ locate_debug_info (unw_addr_space_t as, struct dl_phdr_info *info,
       as->debug_frames = fdesc;
     }
   
-  if (name && name != dlname)
-    free (name);
-  
   return fdesc;
 }
 
