[PATCH] elfcmp: Fix leaking Ebl handles.
by Mark Wielaard
open_file () explicitly gets Ebl handles for both Elf files to compare.
Make sure to close those when done.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 4 ++++
src/elfcmp.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/src/ChangeLog b/src/ChangeLog
index d6d2936..27c638f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2015-12-01 Mark Wielaard <mjw(a)redhat.com>
+
+ * elfcmp.c (main): Close ebl1 and ebl2 backends.
+
2015-10-16 Mark Wielaard <mjw(a)redhat.com>
* Makefile.am [BUILD_STATIC](libdw): Add -lz.
diff --git a/src/elfcmp.c b/src/elfcmp.c
index 0250fbe..852b92f 100644
--- a/src/elfcmp.c
+++ b/src/elfcmp.c
@@ -655,6 +655,8 @@ cannot read note section [%zu] '%s' in '%s': %s"),
out:
elf_end (elf1);
elf_end (elf2);
+ ebl_closebackend (ebl1);
+ ebl_closebackend (ebl2);
close (fd1);
close (fd2);
--
2.5.0
8 years, 3 months
[PATCH] Move nested functions in dwfl_module_getdwarf.c to file scope.
by Chih-Hung Hsieh
* In dwfl_module_getdwarf.c, nested functions 'consider_shdr'
and 'translate_offs' are moved to file scope to compile with clang.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdwfl/ChangeLog | 7 +
libdwfl/dwfl_module_getdwarf.c | 301 +++++++++++++++++++++--------------------
2 files changed, 160 insertions(+), 148 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 163a6f1..aac9e79 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2015-11-16 Chih-Hung Hsieh <chh(a)google.com>
+
+ * dwfl_module_getdwarf.c (find_prelink_address_sync): Move nested
+ function 'consider_shdr' to file scope.
+ * dwfl_module_getdwarf.c (find_dynsym): Move nested function
+ 'translate_offs' to file scope.
+
2015-11-13 Chih-Hung Hsieh <chh(a)google.com>
* gzip.c (unzip): Move nested functions to file scope.
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 8483fa2..4d46d2f 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -34,6 +34,14 @@
#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
#include "../libelf/libelfP.h"
+enum {
+ i_symtab,
+ i_strtab,
+ i_hash,
+ i_gnu_hash,
+ i_max
+};
+
static inline Dwfl_Error
open_elf_file (Elf **elf, int *fd, char **name)
{
@@ -231,6 +239,24 @@ __libdwfl_getelf (Dwfl_Module *mod)
mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
}
+static inline void
+consider_shdr (GElf_Addr interp,
+ GElf_Word sh_type,
+ GElf_Xword sh_flags,
+ GElf_Addr sh_addr,
+ GElf_Xword sh_size,
+ GElf_Addr *phighest)
+{
+ if ((sh_flags & SHF_ALLOC)
+ && ((sh_type == SHT_PROGBITS && sh_addr != interp)
+ || sh_type == SHT_NOBITS))
+ {
+ const GElf_Addr sh_end = sh_addr + sh_size;
+ if (sh_end > *phighest)
+ *phighest = sh_end;
+ }
+}
+
/* If the main file might have been prelinked, then we need to
discover the correct synchronization address between the main and
debug files. Because of prelink's section juggling, we cannot rely
@@ -448,22 +474,6 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
GElf_Addr highest;
- inline void consider_shdr (GElf_Addr interp,
- GElf_Word sh_type,
- GElf_Xword sh_flags,
- GElf_Addr sh_addr,
- GElf_Xword sh_size)
- {
- if ((sh_flags & SHF_ALLOC)
- && ((sh_type == SHT_PROGBITS && sh_addr != interp)
- || sh_type == SHT_NOBITS))
- {
- const GElf_Addr sh_end = sh_addr + sh_size;
- if (sh_end > highest)
- highest = sh_end;
- }
- }
-
highest = 0;
scn = NULL;
while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
@@ -476,7 +486,7 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
return DWFL_E_LIBELF;
}
consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
- sh->sh_addr, sh->sh_size);
+ sh->sh_addr, sh->sh_size, &highest);
}
if (highest > mod->main.vaddr)
{
@@ -489,7 +499,7 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
for (size_t i = 0; i < shnum - 1; ++i)
consider_shdr (undo_interp, (*s32)[i].sh_type,
(*s32)[i].sh_flags, (*s32)[i].sh_addr,
- (*s32)[i].sh_size);
+ (*s32)[i].sh_size, &highest);
}
else
{
@@ -497,7 +507,7 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
for (size_t i = 0; i < shnum - 1; ++i)
consider_shdr (undo_interp, (*s64)[i].sh_type,
(*s64)[i].sh_flags, (*s64)[i].sh_addr,
- (*s64)[i].sh_size);
+ (*s64)[i].sh_size, &highest);
}
if (highest > file->vaddr)
@@ -676,6 +686,128 @@ find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n,
}
}
+/* Translate pointers into file offsets. ADJUST is either zero
+ in case the dynamic segment wasn't adjusted or mod->main_bias. */
+static void
+translate_offs (GElf_Addr adjust,
+ Dwfl_Module *mod, size_t phnum,
+ GElf_Addr addrs[i_max], GElf_Xword strsz,
+ GElf_Ehdr *ehdr, Elf_Data **pdata)
+{
+ GElf_Off offs[i_max] = { 0, };
+ find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs);
+
+ /* Figure out the size of the symbol table. */
+ if (offs[i_hash] != 0)
+ {
+ /* In the original format, .hash says the size of .dynsym. */
+
+ size_t entsz = SH_ENTSIZE_HASH (ehdr);
+ *pdata = elf_getdata_rawchunk (mod->main.elf,
+ offs[i_hash] + entsz, entsz,
+ entsz == 4 ? ELF_T_WORD
+ : ELF_T_XWORD);
+ if (*pdata != NULL)
+ mod->syments = (entsz == 4
+ ? *(const GElf_Word *) (*pdata)->d_buf
+ : *(const GElf_Xword *) (*pdata)->d_buf);
+ }
+ if (offs[i_gnu_hash] != 0 && mod->syments == 0)
+ {
+ /* In the new format, we can derive it with some work. */
+
+ const struct
+ {
+ Elf32_Word nbuckets;
+ Elf32_Word symndx;
+ Elf32_Word maskwords;
+ Elf32_Word shift2;
+ } *header;
+
+ *pdata = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
+ sizeof *header, ELF_T_WORD);
+ if (*pdata != NULL)
+ {
+ header = (*pdata)->d_buf;
+ Elf32_Word nbuckets = header->nbuckets;
+ Elf32_Word symndx = header->symndx;
+ GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
+ + (gelf_getclass (mod->main.elf)
+ * sizeof (Elf32_Word)
+ * header->maskwords));
+
+ // elf_getdata_rawchunk takes a size_t, make sure it
+ // doesn't overflow.
+#if SIZE_MAX <= UINT32_MAX
+ if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
+ *pdata = NULL;
+ else
+#endif
+ *pdata = elf_getdata_rawchunk (mod->main.elf, buckets_at,
+ nbuckets * sizeof (Elf32_Word),
+ ELF_T_WORD);
+ if (*pdata != NULL && symndx < nbuckets)
+ {
+ const Elf32_Word *const buckets = (*pdata)->d_buf;
+ Elf32_Word maxndx = symndx;
+ for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
+ if (buckets[bucket] > maxndx)
+ maxndx = buckets[bucket];
+
+ GElf_Off hasharr_at = (buckets_at
+ + nbuckets * sizeof (Elf32_Word));
+ hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
+ do
+ {
+ *pdata = elf_getdata_rawchunk (mod->main.elf,
+ hasharr_at,
+ sizeof (Elf32_Word),
+ ELF_T_WORD);
+ if (*pdata != NULL
+ && (*(const Elf32_Word *) (*pdata)->d_buf & 1u))
+ {
+ mod->syments = maxndx + 1;
+ break;
+ }
+ ++maxndx;
+ hasharr_at += sizeof (Elf32_Word);
+ } while (*pdata != NULL);
+ }
+ }
+ }
+ if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
+ mod->syments = ((offs[i_strtab] - offs[i_symtab])
+ / gelf_fsize (mod->main.elf,
+ ELF_T_SYM, 1, EV_CURRENT));
+
+ if (mod->syments > 0)
+ {
+ mod->symdata = elf_getdata_rawchunk (mod->main.elf,
+ offs[i_symtab],
+ gelf_fsize (mod->main.elf,
+ ELF_T_SYM,
+ mod->syments,
+ EV_CURRENT),
+ ELF_T_SYM);
+ if (mod->symdata != NULL)
+ {
+ mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
+ offs[i_strtab],
+ strsz,
+ ELF_T_BYTE);
+ if (mod->symstrdata == NULL)
+ mod->symdata = NULL;
+ }
+ if (mod->symdata == NULL)
+ mod->symerr = DWFL_E (LIBELF, elf_errno ());
+ else
+ {
+ mod->symfile = &mod->main;
+ mod->symerr = DWFL_E_NOERROR;
+ }
+ }
+}
+
/* Try to find a dynamic symbol table via phdrs. */
static void
find_dynsym (Dwfl_Module *mod)
@@ -704,14 +836,6 @@ find_dynsym (Dwfl_Module *mod)
if (data == NULL)
continue;
- enum
- {
- i_symtab,
- i_strtab,
- i_hash,
- i_gnu_hash,
- i_max
- };
GElf_Addr addrs[i_max] = { 0, };
GElf_Xword strsz = 0;
size_t n = data->d_size / gelf_fsize (mod->main.elf,
@@ -752,131 +876,12 @@ find_dynsym (Dwfl_Module *mod)
break;
}
- /* Translate pointers into file offsets. ADJUST is either zero
- in case the dynamic segment wasn't adjusted or mod->main_bias. */
- void translate_offs (GElf_Addr adjust)
- {
- GElf_Off offs[i_max] = { 0, };
- find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs);
-
- /* Figure out the size of the symbol table. */
- if (offs[i_hash] != 0)
- {
- /* In the original format, .hash says the size of .dynsym. */
-
- size_t entsz = SH_ENTSIZE_HASH (ehdr);
- data = elf_getdata_rawchunk (mod->main.elf,
- offs[i_hash] + entsz, entsz,
- entsz == 4 ? ELF_T_WORD
- : ELF_T_XWORD);
- if (data != NULL)
- mod->syments = (entsz == 4
- ? *(const GElf_Word *) data->d_buf
- : *(const GElf_Xword *) data->d_buf);
- }
- if (offs[i_gnu_hash] != 0 && mod->syments == 0)
- {
- /* In the new format, we can derive it with some work. */
-
- const struct
- {
- Elf32_Word nbuckets;
- Elf32_Word symndx;
- Elf32_Word maskwords;
- Elf32_Word shift2;
- } *header;
-
- data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
- sizeof *header, ELF_T_WORD);
- if (data != NULL)
- {
- header = data->d_buf;
- Elf32_Word nbuckets = header->nbuckets;
- Elf32_Word symndx = header->symndx;
- GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
- + (gelf_getclass (mod->main.elf)
- * sizeof (Elf32_Word)
- * header->maskwords));
-
- // elf_getdata_rawchunk takes a size_t, make sure it
- // doesn't overflow.
-#if SIZE_MAX <= UINT32_MAX
- if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
- data = NULL;
- else
-#endif
- data
- = elf_getdata_rawchunk (mod->main.elf, buckets_at,
- nbuckets * sizeof (Elf32_Word),
- ELF_T_WORD);
- if (data != NULL && symndx < nbuckets)
- {
- const Elf32_Word *const buckets = data->d_buf;
- Elf32_Word maxndx = symndx;
- for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
- if (buckets[bucket] > maxndx)
- maxndx = buckets[bucket];
-
- GElf_Off hasharr_at = (buckets_at
- + nbuckets * sizeof (Elf32_Word));
- hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
- do
- {
- data = elf_getdata_rawchunk (mod->main.elf,
- hasharr_at,
- sizeof (Elf32_Word),
- ELF_T_WORD);
- if (data != NULL
- && (*(const Elf32_Word *) data->d_buf & 1u))
- {
- mod->syments = maxndx + 1;
- break;
- }
- ++maxndx;
- hasharr_at += sizeof (Elf32_Word);
- } while (data != NULL);
- }
- }
- }
- if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
- mod->syments = ((offs[i_strtab] - offs[i_symtab])
- / gelf_fsize (mod->main.elf,
- ELF_T_SYM, 1, EV_CURRENT));
-
- if (mod->syments > 0)
- {
- mod->symdata = elf_getdata_rawchunk (mod->main.elf,
- offs[i_symtab],
- gelf_fsize (mod->main.elf,
- ELF_T_SYM,
- mod->syments,
- EV_CURRENT),
- ELF_T_SYM);
- if (mod->symdata != NULL)
- {
- mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
- offs[i_strtab],
- strsz,
- ELF_T_BYTE);
- if (mod->symstrdata == NULL)
- mod->symdata = NULL;
- }
- if (mod->symdata == NULL)
- mod->symerr = DWFL_E (LIBELF, elf_errno ());
- else
- {
- mod->symfile = &mod->main;
- mod->symerr = DWFL_E_NOERROR;
- }
- }
- }
-
/* First try unadjusted, like ELF files from disk, vdso.
Then try for already adjusted dynamic section, like ELF
from remote memory. */
- translate_offs (0);
+ translate_offs (0, mod, phnum, addrs, strsz, ehdr, &data);
if (mod->symfile == NULL)
- translate_offs (mod->main_bias);
+ translate_offs (mod->main_bias, mod, phnum, addrs, strsz, ehdr, &data);
return;
}
--
2.6.0.rc2.230.g3dd15c0
8 years, 3 months
[PATCH] Move nested functions in dwfl_module_addrsym.c to file scope.
by Chih-Hung Hsieh
* Move nested functions 'same_section', 'binding_value',
'try_sym_value', and 'search_table'.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdwfl/ChangeLog | 6 +
libdwfl/dwfl_module_addrsym.c | 326 +++++++++++++++++++++++-------------------
2 files changed, 183 insertions(+), 149 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 163a6f1..1ce4274 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-16 Chih-Hung Hsieh <chh(a)google.com>
+
+ * dwfl_module_addrsym.c (__libdwfl_addrsym): Move nested functions
+ 'same_section', 'binding_value', 'try_sym_value', and 'search_table'
+ to file scope.
+
2015-11-13 Chih-Hung Hsieh <chh(a)google.com>
* gzip.c (unzip): Move nested functions to file scope.
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index d205832..1aff02c 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -28,141 +28,136 @@
#include "libdwflP.h"
-/* Returns the name of the symbol "closest" to ADDR.
- Never returns symbols at addresses above ADDR. */
+struct search_state {
+ Dwfl_Module *mod;
+ GElf_Addr addr;
+ GElf_Sym *closest_sym;
+ bool adjust_st_value;
+ GElf_Word addr_shndx;
+ Elf *addr_symelf;
+ /* Keep track of the closest symbol we have seen so far.
+ Here we store only symbols with nonzero st_size. */
+ const char *closest_name;
+ GElf_Addr closest_value;
+ GElf_Word closest_shndx;
+ Elf *closest_elf;
+ /* Keep track of an eligible symbol with st_size == 0 as a fallback. */
+ const char *sizeless_name;
+ GElf_Sym sizeless_sym;
+ GElf_Addr sizeless_value;
+ GElf_Word sizeless_shndx;
+ Elf *sizeless_elf;
+ /* Keep track of the lowest address a relevant sizeless symbol could have. */
+ GElf_Addr min_label;
+};
-const char *
-internal_function
-__libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
- GElf_Sym *closest_sym, GElf_Word *shndxp,
- Elf **elfp, Dwarf_Addr *biasp, bool adjust_st_value)
+/* Return true iff we consider ADDR to lie in the same section as SYM. */
+static inline bool
+same_section (struct search_state *state, GElf_Addr value, Elf *symelf, GElf_Word shndx)
{
- int syments = INTUSE(dwfl_module_getsymtab) (mod);
- if (syments < 0)
- return NULL;
+ /* For absolute symbols and the like, only match exactly. */
+ if (shndx >= SHN_LORESERVE)
+ return value == state->addr;
- /* Return true iff we consider ADDR to lie in the same section as SYM. */
- GElf_Word addr_shndx = SHN_UNDEF;
- Elf *addr_symelf = NULL;
- inline bool same_section (GElf_Addr value, Elf *symelf, GElf_Word shndx)
+ /* If value might not be st_value, the shndx of the symbol might
+ not match the section of the value. Explicitly look both up. */
+ if (! state->adjust_st_value)
{
- /* For absolute symbols and the like, only match exactly. */
- if (shndx >= SHN_LORESERVE)
- return value == addr;
-
- /* If value might not be st_value, the shndx of the symbol might
- not match the section of the value. Explicitly look both up. */
- if (! adjust_st_value)
- {
- Dwarf_Addr v;
- if (addr_shndx == SHN_UNDEF)
- {
- v = addr;
- addr_shndx = __libdwfl_find_section_ndx (mod, &v);
- }
+ Dwarf_Addr v;
+ if (state->addr_shndx == SHN_UNDEF)
+ {
+ v = state->addr;
+ state->addr_shndx = __libdwfl_find_section_ndx (state->mod, &v);
+ }
- v = value;
- return addr_shndx == __libdwfl_find_section_ndx (mod, &v);
- }
-
- /* Figure out what section ADDR lies in. */
- if (addr_shndx == SHN_UNDEF || addr_symelf != symelf)
- {
- GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, symelf, addr);
- Elf_Scn *scn = NULL;
- addr_shndx = SHN_ABS;
- addr_symelf = symelf;
- while ((scn = elf_nextscn (symelf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (likely (shdr != NULL)
- && mod_addr >= shdr->sh_addr
- && mod_addr < shdr->sh_addr + shdr->sh_size)
- {
- addr_shndx = elf_ndxscn (scn);
- break;
- }
- }
- }
-
- return shndx == addr_shndx && addr_symelf == symelf;
+ v = value;
+ return state->addr_shndx == __libdwfl_find_section_ndx (state->mod, &v);
}
- /* Keep track of the closest symbol we have seen so far.
- Here we store only symbols with nonzero st_size. */
- const char *closest_name = NULL;
- GElf_Addr closest_value = 0;
- GElf_Word closest_shndx = SHN_UNDEF;
- Elf *closest_elf = NULL;
+ /* Figure out what section ADDR lies in. */
+ if (state->addr_shndx == SHN_UNDEF || state->addr_symelf != symelf)
+ {
+ GElf_Addr mod_addr = dwfl_deadjust_st_value (state->mod, symelf, state->addr);
+ Elf_Scn *scn = NULL;
+ state->addr_shndx = SHN_ABS;
+ state->addr_symelf = symelf;
+ while ((scn = elf_nextscn (symelf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (likely (shdr != NULL)
+ && mod_addr >= shdr->sh_addr
+ && mod_addr < shdr->sh_addr + shdr->sh_size)
+ {
+ state->addr_shndx = elf_ndxscn (scn);
+ break;
+ }
+ }
+ }
- /* Keep track of an eligible symbol with st_size == 0 as a fallback. */
- const char *sizeless_name = NULL;
- GElf_Sym sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF };
- GElf_Addr sizeless_value = 0;
- GElf_Word sizeless_shndx = SHN_UNDEF;
- Elf *sizeless_elf = NULL;
+ return shndx == state->addr_shndx && state->addr_symelf == symelf;
+}
- /* Keep track of the lowest address a relevant sizeless symbol could have. */
- GElf_Addr min_label = 0;
+/* Return GELF_ST_BIND as higher-is-better integer. */
+static inline int
+binding_value (const GElf_Sym *symp)
+{
+ switch (GELF_ST_BIND (symp->st_info))
+ {
+ case STB_GLOBAL:
+ return 3;
+ case STB_WEAK:
+ return 2;
+ case STB_LOCAL:
+ return 1;
+ default:
+ return 0;
+ }
+}
- /* Try one symbol and associated value from the search table. */
- inline void try_sym_value (GElf_Addr value, GElf_Sym *sym,
- const char *name, GElf_Word shndx,
- Elf *elf, bool resolved)
- {
+/* Try one symbol and associated value from the search table. */
+static inline void
+try_sym_value (struct search_state *state,
+ GElf_Addr value, GElf_Sym *sym,
+ const char *name, GElf_Word shndx,
+ Elf *elf, bool resolved)
+{
/* Even if we don't choose this symbol, its existence excludes
any sizeless symbol (assembly label) that is below its upper
bound. */
- if (value + sym->st_size > min_label)
- min_label = value + sym->st_size;
+ if (value + sym->st_size > state->min_label)
+ state->min_label = value + sym->st_size;
- if (sym->st_size == 0 || addr - value < sym->st_size)
+ if (sym->st_size == 0 || state->addr - value < sym->st_size)
{
- /* Return GELF_ST_BIND as higher-is-better integer. */
- inline int binding_value (const GElf_Sym *symp)
- {
- switch (GELF_ST_BIND (symp->st_info))
- {
- case STB_GLOBAL:
- return 3;
- case STB_WEAK:
- return 2;
- case STB_LOCAL:
- return 1;
- default:
- return 0;
- }
- }
-
/* This symbol is a better candidate than the current one
if it's closer to ADDR or is global when it was local. */
- if (closest_name == NULL
- || closest_value < value
- || binding_value (closest_sym) < binding_value (sym))
+ if (state->closest_name == NULL
+ || state->closest_value < value
+ || binding_value (state->closest_sym) < binding_value (sym))
{
if (sym->st_size != 0)
{
- *closest_sym = *sym;
- closest_value = value;
- closest_shndx = shndx;
- closest_elf = elf;
- closest_name = name;
+ *state->closest_sym = *sym;
+ state->closest_value = value;
+ state->closest_shndx = shndx;
+ state->closest_elf = elf;
+ state->closest_name = name;
}
- else if (closest_name == NULL
- && value >= min_label
- && same_section (value,
- resolved ? mod->main.elf : elf, shndx))
+ else if (state->closest_name == NULL
+ && value >= state->min_label
+ && same_section (state, value,
+ resolved ? state->mod->main.elf : elf, shndx))
{
/* Handwritten assembly symbols sometimes have no
st_size. If no symbol with proper size includes
the address, we'll use the closest one that is in
the same section as ADDR. */
- sizeless_sym = *sym;
- sizeless_value = value;
- sizeless_shndx = shndx;
- sizeless_elf = elf;
- sizeless_name = name;
+ state->sizeless_sym = *sym;
+ state->sizeless_value = value;
+ state->sizeless_shndx = shndx;
+ state->sizeless_elf = elf;
+ state->sizeless_name = name;
}
}
/* When the beginning of its range is no closer,
@@ -170,26 +165,27 @@ __libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
GELF_ST_BIND preference. If all are equal prefer
the first symbol found. */
else if (sym->st_size != 0
- && closest_value == value
- && ((closest_sym->st_size > sym->st_size
- && (binding_value (closest_sym)
+ && state->closest_value == value
+ && ((state->closest_sym->st_size > sym->st_size
+ && (binding_value (state->closest_sym)
<= binding_value (sym)))
- || (closest_sym->st_size >= sym->st_size
- && (binding_value (closest_sym)
+ || (state->closest_sym->st_size >= sym->st_size
+ && (binding_value (state->closest_sym)
< binding_value (sym)))))
{
- *closest_sym = *sym;
- closest_value = value;
- closest_shndx = shndx;
- closest_elf = elf;
- closest_name = name;
+ *state->closest_sym = *sym;
+ state->closest_value = value;
+ state->closest_shndx = shndx;
+ state->closest_elf = elf;
+ state->closest_name = name;
}
}
- }
+}
- /* Look through the symbol table for a matching symbol. */
- inline void search_table (int start, int end)
- {
+/* Look through the symbol table for a matching symbol. */
+static inline void
+search_table (struct search_state *state, int start, int end)
+{
for (int i = start; i < end; ++i)
{
GElf_Sym sym;
@@ -197,32 +193,64 @@ __libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
GElf_Word shndx;
Elf *elf;
bool resolved;
- const char *name = __libdwfl_getsym (mod, i, &sym, &value,
+ const char *name = __libdwfl_getsym (state->mod, i, &sym, &value,
&shndx, &elf, NULL,
- &resolved, adjust_st_value);
+ &resolved, state->adjust_st_value);
if (name != NULL && name[0] != '\0'
&& sym.st_shndx != SHN_UNDEF
- && value <= addr
+ && value <= state->addr
&& GELF_ST_TYPE (sym.st_info) != STT_SECTION
&& GELF_ST_TYPE (sym.st_info) != STT_FILE
&& GELF_ST_TYPE (sym.st_info) != STT_TLS)
{
- try_sym_value (value, &sym, name, shndx, elf, resolved);
+ try_sym_value (state, value, &sym, name, shndx, elf, resolved);
/* If this is an addrinfo variant and the value could be
resolved then also try matching the (adjusted) st_value. */
- if (resolved && mod->e_type != ET_REL)
+ if (resolved && state->mod->e_type != ET_REL)
{
GElf_Addr adjusted_st_value;
- adjusted_st_value = dwfl_adjusted_st_value (mod, elf,
+ adjusted_st_value = dwfl_adjusted_st_value (state->mod, elf,
sym.st_value);
- if (value != adjusted_st_value && adjusted_st_value <= addr)
- try_sym_value (adjusted_st_value, &sym, name, shndx,
+ if (value != adjusted_st_value && adjusted_st_value <= state->addr)
+ try_sym_value (state, adjusted_st_value, &sym, name, shndx,
elf, false);
}
}
}
- }
+}
+
+/* Returns the name of the symbol "closest" to ADDR.
+ Never returns symbols at addresses above ADDR. */
+const char *
+internal_function
+__libdwfl_addrsym (Dwfl_Module *_mod, GElf_Addr _addr, GElf_Off *off,
+ GElf_Sym *_closest_sym, GElf_Word *shndxp,
+ Elf **elfp, Dwarf_Addr *biasp, bool _adjust_st_value)
+{
+ int syments = INTUSE(dwfl_module_getsymtab) (_mod);
+ if (syments < 0)
+ return NULL;
+
+ struct search_state state =
+ {
+ .addr = _addr,
+ .mod = _mod,
+ .closest_sym = _closest_sym,
+ .adjust_st_value = _adjust_st_value,
+ .addr_shndx = SHN_UNDEF,
+ .addr_symelf = NULL,
+ .closest_name = NULL,
+ .closest_value = 0,
+ .closest_shndx = SHN_UNDEF,
+ .closest_elf = NULL,
+ .sizeless_name = NULL,
+ .sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF },
+ .sizeless_value = 0,
+ .sizeless_shndx = SHN_UNDEF,
+ .sizeless_elf = NULL,
+ .min_label = 0
+ };
/* First go through global symbols. mod->first_global and
mod->aux_first_global are setup by dwfl_module_getsymtab to the
@@ -233,38 +261,38 @@ __libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
come first in the symbol table, then all globals. The zeroth,
null entry, in the auxiliary table is skipped if there is a main
table. */
- int first_global = INTUSE (dwfl_module_getsymtab_first_global) (mod);
+ int first_global = INTUSE (dwfl_module_getsymtab_first_global) (state.mod);
if (first_global < 0)
return NULL;
- search_table (first_global == 0 ? 1 : first_global, syments);
+ search_table (&state, first_global == 0 ? 1 : first_global, syments);
/* If we found nothing searching the global symbols, then try the locals.
Unless we have a global sizeless symbol that matches exactly. */
- if (closest_name == NULL && first_global > 1
- && (sizeless_name == NULL || sizeless_value != addr))
- search_table (1, first_global);
+ if (state.closest_name == NULL && first_global > 1
+ && (state.sizeless_name == NULL || state.sizeless_value != state.addr))
+ search_table (&state, 1, first_global);
/* If we found no proper sized symbol to use, fall back to the best
candidate sizeless symbol we found, if any. */
- if (closest_name == NULL
- && sizeless_name != NULL && sizeless_value >= min_label)
+ if (state.closest_name == NULL
+ && state.sizeless_name != NULL && state.sizeless_value >= state.min_label)
{
- *closest_sym = sizeless_sym;
- closest_value = sizeless_value;
- closest_shndx = sizeless_shndx;
- closest_elf = sizeless_elf;
- closest_name = sizeless_name;
+ *state.closest_sym = state.sizeless_sym;
+ state.closest_value = state.sizeless_value;
+ state.closest_shndx = state.sizeless_shndx;
+ state.closest_elf = state.sizeless_elf;
+ state.closest_name = state.sizeless_name;
}
- *off = addr - closest_value;
+ *off = state.addr - state.closest_value;
if (shndxp != NULL)
- *shndxp = closest_shndx;
+ *shndxp = state.closest_shndx;
if (elfp != NULL)
- *elfp = closest_elf;
+ *elfp = state.closest_elf;
if (biasp != NULL)
- *biasp = dwfl_adjusted_st_value (mod, closest_elf, 0);
- return closest_name;
+ *biasp = dwfl_adjusted_st_value (state.mod, state.closest_elf, 0);
+ return state.closest_name;
}
--
2.6.0.rc2.230.g3dd15c0
8 years, 3 months
[PATCH] Move nested functions in dwarf_entry_breakpoints.c to file scope.
by Chih-Hung Hsieh
No nested functions to compile with clang/llvm.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdw/ChangeLog | 5 ++
libdw/dwarf_entry_breakpoints.c | 110 +++++++++++++++++++++-------------------
2 files changed, 64 insertions(+), 51 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 39c49aa..b91c8c7 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-14 Chih-Hung Hsieh <chh(a)google.com>
+
+ * dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Move recursive
+ functions 'add_bkpt', 'entrypc_bkpt', and 'search_range' to file scope.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat
diff --git a/libdw/dwarf_entry_breakpoints.c b/libdw/dwarf_entry_breakpoints.c
index abfee73..c3c0f39 100644
--- a/libdw/dwarf_entry_breakpoints.c
+++ b/libdw/dwarf_entry_breakpoints.c
@@ -34,54 +34,40 @@
#include <stdlib.h>
-int
-dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
+/* Add one breakpoint location to the result vector. */
+static inline int
+add_bkpt (Dwarf_Addr pc, Dwarf_Addr **bkpts, int *pnbkpts)
{
- int nbkpts = 0;
- *bkpts = NULL;
-
- /* Add one breakpoint location to the result vector. */
- inline int add_bkpt (Dwarf_Addr pc)
- {
- Dwarf_Addr *newlist = realloc (*bkpts, ++nbkpts * sizeof newlist[0]);
- if (newlist == NULL)
- {
- free (*bkpts);
- *bkpts = NULL;
- __libdw_seterrno (DWARF_E_NOMEM);
- return -1;
- }
- newlist[nbkpts - 1] = pc;
- *bkpts = newlist;
- return nbkpts;
- }
-
- /* Fallback result, break at the entrypc/lowpc value. */
- inline int entrypc_bkpt (void)
+ Dwarf_Addr *newlist = realloc (*bkpts, ++(*pnbkpts) * sizeof newlist[0]);
+ if (newlist == NULL)
{
- Dwarf_Addr pc;
- return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc);
- }
-
- /* Fetch the CU's line records to look for this DIE's addresses. */
- Dwarf_Die cudie = CUDIE (die->cu);
- Dwarf_Lines *lines;
- size_t nlines;
- if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0)
- {
- int error = INTUSE (dwarf_errno) ();
- if (error == 0) /* CU has no DW_AT_stmt_list. */
- return entrypc_bkpt ();
- __libdw_seterrno (error);
+ free (*bkpts);
+ *bkpts = NULL;
+ __libdw_seterrno (DWARF_E_NOMEM);
return -1;
}
+ newlist[*pnbkpts - 1] = pc;
+ *bkpts = newlist;
+ return *pnbkpts;
+}
- /* Search a contiguous PC range for prologue-end markers.
- If DWARF, look for proper markers.
- Failing that, if ADHOC, look for the ad hoc convention. */
- inline int search_range (Dwarf_Addr low, Dwarf_Addr high,
- bool dwarf, bool adhoc)
- {
+/* Fallback result, break at the entrypc/lowpc value. */
+static inline int
+entrypc_bkpt (Dwarf_Die *die, Dwarf_Addr **bkpts, int *pnbkpts)
+{
+ Dwarf_Addr pc;
+ return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc, bkpts, pnbkpts);
+}
+
+/* Search a contiguous PC range for prologue-end markers.
+ If DWARF, look for proper markers.
+ Failing that, if ADHOC, look for the ad hoc convention. */
+static inline int
+search_range (Dwarf_Addr low, Dwarf_Addr high,
+ bool dwarf, bool adhoc,
+ Dwarf_Lines *lines, size_t nlines,
+ Dwarf_Addr **bkpts, int *pnbkpts)
+{
size_t l = 0, u = nlines;
while (l < u)
{
@@ -103,16 +89,35 @@ dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
if (dwarf)
for (size_t i = l; i < u && lines->info[i].addr < high; ++i)
if (lines->info[i].prologue_end
- && add_bkpt (lines->info[i].addr) < 0)
+ && add_bkpt (lines->info[i].addr, bkpts, pnbkpts) < 0)
return -1;
- if (adhoc && nbkpts == 0)
+ if (adhoc && *pnbkpts == 0)
while (++l < nlines && lines->info[l].addr < high)
if (!lines->info[l].end_sequence)
- return add_bkpt (lines->info[l].addr);
- return nbkpts;
+ return add_bkpt (lines->info[l].addr, bkpts, pnbkpts);
+ return *pnbkpts;
}
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return -1;
+}
+
+int
+dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
+{
+ int nbkpts = 0;
+ *bkpts = NULL;
+
+ /* Fetch the CU's line records to look for this DIE's addresses. */
+ Dwarf_Die cudie = CUDIE (die->cu);
+ Dwarf_Lines *lines;
+ size_t nlines;
+ if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0)
+ {
+ int error = INTUSE (dwarf_errno) ();
+ if (error == 0) /* CU has no DW_AT_stmt_list. */
+ return entrypc_bkpt (die, bkpts, &nbkpts);
+ __libdw_seterrno (error);
+ return -1;
}
/* Search each contiguous address range for DWARF prologue_end markers. */
@@ -126,14 +131,16 @@ dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
/* Most often there is a single contiguous PC range for the DIE. */
if (offset == 1)
- return search_range (begin, end, true, true) ?: entrypc_bkpt ();
+ return search_range (begin, end, true, true, lines, nlines, bkpts, &nbkpts)
+ ?: entrypc_bkpt (die, bkpts, &nbkpts);
Dwarf_Addr lowpc = (Dwarf_Addr) -1l;
Dwarf_Addr highpc = (Dwarf_Addr) -1l;
while (offset > 0)
{
/* We have an address range entry. */
- if (search_range (begin, end, true, false) < 0)
+ if (search_range (begin, end, true, false,
+ lines, nlines, bkpts, &nbkpts) < 0)
return -1;
if (begin < lowpc)
@@ -150,6 +157,7 @@ dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
fall back to just using the entrypc value. */
return (nbkpts
?: (lowpc == (Dwarf_Addr) -1l ? 0
- : search_range (lowpc, highpc, false, true))
- ?: entrypc_bkpt ());
+ : search_range (lowpc, highpc, false, true,
+ lines, nlines, bkpts, &nbkpts))
+ ?: entrypc_bkpt (die, bkpts, &nbkpts));
}
--
2.6.0.rc2.230.g3dd15c0
8 years, 3 months
[PATCH] Move nested functions in libdw_visit_scopes.c to file scope.
by Chih-Hung Hsieh
* No nested functions to compile with clang/llvm.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdw/ChangeLog | 5 ++
libdw/libdw_visit_scopes.c | 163 +++++++++++++++++++++++++--------------------
2 files changed, 95 insertions(+), 73 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 39c49aa..56ee808 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-14 Chih-Hung Hsieh <chh(a)google.com>
+
+ * libdw_visit_scopes.c (__libdw_visit_scopes): Move recursive nested
+ function 'walk_children' to file scope; inline 'recurse' at its call site.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat
diff --git a/libdw/libdw_visit_scopes.c b/libdw/libdw_visit_scopes.c
index 5e5c26f..9cd5bad 100644
--- a/libdw/libdw_visit_scopes.c
+++ b/libdw/libdw_visit_scopes.c
@@ -64,6 +64,22 @@ may_have_scopes (Dwarf_Die *die)
return false;
}
+struct walk_children_state {
+ /* Parameters of __libdw_visit_scopes. */
+ unsigned int depth;
+ struct Dwarf_Die_Chain *imports;
+ int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+ int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+ void *arg;
+ /* Return value of recursive walker. */
+ int ret;
+ /* Extra local variables for the walker. */
+ struct Dwarf_Die_Chain child;
+};
+
+static inline int
+walk_children (struct walk_children_state *state);
+
int
internal_function
__libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root,
@@ -76,95 +92,96 @@ __libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root,
void *),
void *arg)
{
- struct Dwarf_Die_Chain child;
- int ret;
-
- child.parent = root;
- if ((ret = INTUSE(dwarf_child) (&root->die, &child.die)) != 0)
- return ret < 0 ? -1 : 0; // Having zero children is legal.
-
- inline int recurse (void)
+ struct walk_children_state state =
{
- return __libdw_visit_scopes (depth + 1, &child, imports,
- previsit, postvisit, arg);
- }
-
- /* Checks the given DIE hasn't been imported yet to prevent cycles. */
- inline bool imports_contains (Dwarf_Die *die)
- {
- for (struct Dwarf_Die_Chain *import = imports; import != NULL;
- import = import->parent)
- if (import->die.addr == die->addr)
- return true;
-
- return false;
- }
+ .depth = depth,
+ .imports = imports,
+ .previsit = previsit,
+ .postvisit = postvisit,
+ .arg = arg
+ };
+
+ state.child.parent = root;
+ if ((state.ret = INTUSE(dwarf_child) (&root->die, &state.child.die)) != 0)
+ return state.ret < 0 ? -1 : 0; // Having zero children is legal.
+
+ return walk_children (&state);
+}
- inline int walk_children (void)
+static inline int
+walk_children (struct walk_children_state *state)
{
- do
- {
- /* For an imported unit, it is logically as if the children of
- that unit are siblings of the other children. So don't do
- a full recursion into the imported unit, but just walk the
- children in place before moving to the next real child. */
- while (INTUSE(dwarf_tag) (&child.die) == DW_TAG_imported_unit)
- {
- Dwarf_Die orig_child_die = child.die;
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child.die,
- DW_AT_import,
- &attr_mem);
- if (INTUSE(dwarf_formref_die) (attr, &child.die) != NULL
- && INTUSE(dwarf_child) (&child.die, &child.die) == 0)
- {
- if (imports_contains (&orig_child_die))
- {
- __libdw_seterrno (DWARF_E_INVALID_DWARF);
- return -1;
- }
- struct Dwarf_Die_Chain *orig_imports = imports;
- struct Dwarf_Die_Chain import = { .die = orig_child_die,
- .parent = orig_imports };
- imports = &import;
- int result = walk_children ();
- imports = orig_imports;
- if (result != DWARF_CB_OK)
- return result;
- }
-
- /* Any "real" children left? */
- if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die,
- &child.die)) != 0)
- return ret < 0 ? -1 : 0;
- };
-
- child.prune = false;
+ do
+ {
+ /* For an imported unit, it is logically as if the children of
+ that unit are siblings of the other children. So don't do
+ a full recursion into the imported unit, but just walk the
+ children in place before moving to the next real child. */
+ while (INTUSE(dwarf_tag) (&state->child.die) == DW_TAG_imported_unit)
+ {
+ Dwarf_Die orig_child_die = state->child.die;
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&state->child.die,
+ DW_AT_import,
+ &attr_mem);
+ if (INTUSE(dwarf_formref_die) (attr, &state->child.die) != NULL
+ && INTUSE(dwarf_child) (&state->child.die, &state->child.die) == 0)
+ {
+ /* Checks the given DIE hasn't been imported yet
+ to prevent cycles. */
+ bool imported = false;
+ for (struct Dwarf_Die_Chain *import = state->imports; import != NULL;
+ import = import->parent)
+ if (import->die.addr == orig_child_die.addr)
+ {
+ imported = true;
+ break;
+ }
+ if (imported)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+ struct Dwarf_Die_Chain *orig_imports = state->imports;
+ struct Dwarf_Die_Chain import = { .die = orig_child_die,
+ .parent = orig_imports };
+ state->imports = &import;
+ int result = walk_children (state);
+ state->imports = orig_imports;
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+
+ /* Any "real" children left? */
+ if ((state->ret = INTUSE(dwarf_siblingof) (&orig_child_die,
+ &state->child.die)) != 0)
+ return state->ret < 0 ? -1 : 0;
+ };
+
+ state->child.prune = false;
/* previsit is declared NN */
- int result = (*previsit) (depth + 1, &child, arg);
+ int result = (*state->previsit) (state->depth + 1, &state->child, state->arg);
if (result != DWARF_CB_OK)
return result;
- if (!child.prune && may_have_scopes (&child.die)
- && INTUSE(dwarf_haschildren) (&child.die))
+ if (!state->child.prune && may_have_scopes (&state->child.die)
+ && INTUSE(dwarf_haschildren) (&state->child.die))
{
- result = recurse ();
+ result = __libdw_visit_scopes (state->depth + 1, &state->child, state->imports,
+ state->previsit, state->postvisit, state->arg);
if (result != DWARF_CB_OK)
return result;
}
- if (postvisit != NULL)
+ if (state->postvisit != NULL)
{
- result = (*postvisit) (depth + 1, &child, arg);
+ result = (*state->postvisit) (state->depth + 1, &state->child, state->arg);
if (result != DWARF_CB_OK)
return result;
}
- }
- while ((ret = INTUSE(dwarf_siblingof) (&child.die, &child.die)) == 0);
-
- return ret < 0 ? -1 : 0;
- }
+ }
+ while ((state->ret = INTUSE(dwarf_siblingof) (&state->child.die, &state->child.die)) == 0);
- return walk_children ();
+ return state->ret < 0 ? -1 : 0;
}
--
2.6.0.rc2.230.g3dd15c0
8 years, 3 months
Re: dwfl_thread_getframes: no matching address range
by Kurt Roeckx
On Sun, Dec 27, 2015 at 05:47:50PM +0100, Mark Wielaard wrote:
> On Sun, Dec 27, 2015 at 01:26:59PM +0100, Kurt Roeckx wrote:
> > > Does the same test with 0.163 succeed on the same setup/arch?
> > > If not, did glibc change between the last successful run and
> > > the current failure on that architecture?
> >
> > I didn't see that failure with 0.163. The last 0.163 upload was
> > using glibc 2.19-19, the current version is 2.21-6.
>
> Does the test in 0.164 fail against glibc 2.19-19 on ppc?
Building 0.164 in jessie (stable) works. That's with libc6
2.19-18+deb8u1 and gcc-4.9 4.9.2-10.
> Does the test in 0.163 succeed against glibc 2.21-6 on ppc?
Building 0.163 in unstable also fails with the error.
So it seems that something on the system changed causing the
breakage.
Kurt
8 years, 3 months
Re: dwfl_thread_getframes: no matching address range
by Kurt Roeckx
On Sun, Dec 27, 2015 at 05:47:50PM +0100, Mark Wielaard wrote:
> On Sun, Dec 27, 2015 at 01:26:59PM +0100, Kurt Roeckx wrote:
> > > Does the same test with 0.163 succeed on the same setup/arch?
> > > If not, did glibc change between the last successful run and
> > > the current failure on that architecture?
> >
> > I didn't see that failure with 0.163. The last 0.163 upload was
> > using glibc 2.19-19, the current version is 2.21-6.
>
> Does the test in 0.164 fail against glibc 2.19-19 on ppc?
> Does the test in 0.163 succeed against glibc 2.21-6 on ppc?
I will try this soon, but I'm probably going to test it against
2.19-18+deb8u1 which should be close enough to the -19 version I
think. (Not sure I can install the 2.19-19 version myself.)
> > > You probably need access to a failing setup to debug a bit.
> > > Most interesting would be to see whether or not the glibc.so
> > > has CFI for raise and which addresses that covers.
> > > $ eu-readelf --debug-dump=frame /lib/libc.so.6 | grep -4 '<raise>'
> > > should give you a hint.
> >
> > That just returns:
> > eu-readelf: cannot get debug context descriptor: No DWARF information found
> >
> > (I get that message on working systems too.)
>
> That is just a warning because eu-readelf will try to print both .eh_frame
> and .debug_frame information. It cannot find .debug_frame, but that
> shouldn't be necessary in this case.
>
> > Without the grep it does return all kind of information, just
> > nothing about raise. Both with a 2.19 and 2.21 libc6.so.
>
> That is surprising. I found libc6_2.21-6_powerpc.deb at
> http://ftp.nl.debian.org/debian/pool/main/g/glibc/
> And indeed it doesn't seem to provide unwind info for "raise".
>
> But I cannot find the 2.19-19_powerpc one there. Do you know where I
> could find it, to compare?
If you really want to test 2.19-19, it can be found at:
http://snapshot.debian.org/archive/debian/20150710T034220Z/pool/main/g/gl...
> And if possible where to find the build logs of both and/or the
> debuginfo packages?
The libc6-dbg should be in the same directory in the pool.
Build logs can be found at:
https://buildd.debian.org/status/logs.php?pkg=elfutils&arch=powerpc
Kurt
8 years, 3 months
Re: dwfl_thread_getframes: no matching address range
by Kurt Roeckx
On Sun, Dec 27, 2015 at 03:16:48AM +0100, Mark Wielaard wrote:
> On Sat, Dec 26, 2015 at 11:46:50PM +0100, Kurt Roeckx wrote:
> > I finally uploaded the 0.164 version to Debian, but it's failing
> > in the test suite on most arches with an error message like:
> > dwfl_thread_getframes: no matching address range
> >
> > You can see a full log here:
> > https://buildd.debian.org/status/fetch.php?pkg=elfutils&arch=powerpc&ver=...
>
> That is strange indeed. Especially since a somewhat similar test
> run-backtrace-native.sh does seem to succeed. The output seems to
> indicate that we cannot find the unwind (.eh_frame CFI) for raise
> in this case. But there is not enough info to know for sure.
>
> Does the same test with 0.163 succeed on the same setup/arch?
> If not, did glibc change between the last successful run and
> the current failure on that architecture?
I didn't see that failure with 0.163. The last 0.163 upload was
using glibc 2.19-19, the current version is 2.21-6.
> You probably need access to a failing setup to debug a bit.
> Most interesting would be to see whether or not the glibc.so
> has CFI for raise and which addresses that covers.
> $ eu-readelf --debug-dump=frame /lib/libc.so.6 | grep -4 '<raise>'
> should give you a hint.
That just returns:
eu-readelf: cannot get debug context descriptor: No DWARF information found
(I get that message on working systems too.)
Without the grep it does return all kind of information, just
nothing about raise. Both with a 2.19 and 2.21 libc6.so.
Kurt
8 years, 3 months