mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 15:47:37 +01:00
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.
This commit is contained in:
parent
638302ed73
commit
a2c27a4ab7
2 changed files with 24 additions and 20 deletions
|
@ -124,6 +124,10 @@ if test x$enable_cxx_exceptions = xyes; then
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([SUPPORT_CXX_EXCEPTIONS], [test x$enable_cxx_exceptions = xyes])
|
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
|
LIBUNWIND___THREAD
|
||||||
|
|
||||||
save_LDFLAGS="$LDFLAGS"
|
save_LDFLAGS="$LDFLAGS"
|
||||||
|
|
|
@ -92,6 +92,7 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
|
||||||
return -UNW_ENOINFO;
|
return -UNW_ENOINFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FRAME
|
||||||
/* Load .debug_frame section from FILE. Allocates and returns space
|
/* 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
|
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
|
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)));
|
sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr)));
|
||||||
fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f);
|
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);
|
sec_hdrs[shstrndx].sh_size);
|
||||||
stringtab = malloc (sec_hdrs[shstrndx].sh_size);
|
stringtab = malloc (sec_hdrs[shstrndx].sh_size);
|
||||||
fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET);
|
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);
|
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
|
||||||
fread (*buf, 1, *bufsize, f);
|
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);
|
*bufsize, sec_hdrs[i].sh_offset);
|
||||||
}
|
}
|
||||||
else if (is_local >= 0 && strcmp (secname, ".gnu_debuglink") == 0)
|
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);
|
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
|
||||||
fread (linkbuf, 1, linksize, f);
|
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);
|
*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;
|
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
|
/* 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
|
the name of the binary in *name (space is allocated by the caller)
|
||||||
be freed by the caller). Returns 0 if a binary is successfully found, or 1
|
Returns 0 if a binary is successfully found, or 1 if an error occurs. */
|
||||||
if an error occurs. */
|
|
||||||
|
|
||||||
static int
|
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
|
#ifdef __linux
|
||||||
struct map_iterator mi;
|
struct map_iterator mi;
|
||||||
char path[PATH_MAX];
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
int pid = getpid ();
|
int pid = getpid ();
|
||||||
unsigned long segbase, mapoff, hi;
|
unsigned long segbase, mapoff, hi;
|
||||||
|
|
||||||
maps_init (&mi, pid);
|
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)
|
if (ip >= segbase && ip < hi)
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
maps_close (&mi);
|
maps_close (&mi);
|
||||||
|
return ~found;
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
*name = strdup (path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 1;
|
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)
|
unw_word_t addr, const char *dlname)
|
||||||
{
|
{
|
||||||
struct unw_debug_frame_list *w, *fdesc = 0;
|
struct unw_debug_frame_list *w, *fdesc = 0;
|
||||||
char *name = 0;
|
char path[PATH_MAX];
|
||||||
|
char *name = path;
|
||||||
int err;
|
int err;
|
||||||
uint64_t start = 0, end = 0;
|
uint64_t start = 0, end = 0;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -284,7 +287,7 @@ locate_debug_info (unw_addr_space_t as, struct dl_phdr_info *info,
|
||||||
|
|
||||||
if (strcmp (dlname, "") == 0)
|
if (strcmp (dlname, "") == 0)
|
||||||
{
|
{
|
||||||
err = find_binary_for_address (addr, &name);
|
err = find_binary_for_address (addr, name, sizeof(path));
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n",
|
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;
|
as->debug_frames = fdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name && name != dlname)
|
|
||||||
free (name);
|
|
||||||
|
|
||||||
return fdesc;
|
return fdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue