[patch] Fix uninitialized Dwarf_Frame->regs
by Jan Kratochvil
Hi,
this patch is not required for
[API RFC] unwinder
https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/0026...
to PASS and also it has no effect without -lmcheck.
But with this additional testing only patch
------------------------------------------------------------------------------
diff --git a/libdwfl/dwfl_frame_unwind.c b/libdwfl/dwfl_frame_unwind.c
index da9ed34..c0cb7c9 100644
--- a/libdwfl/dwfl_frame_unwind.c
+++ b/libdwfl/dwfl_frame_unwind.c
@@ -518,6 +518,7 @@ handle_cfi (Dwarf_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod,
}
else if (! expr_eval (state, frame, reg_ops, reg_nops, ®val))
{
+printf("regno %u fail\n", regno);
/* PPC32 vDSO has various invalid operations, ignore them. The
register will look as unset causing an error later, if used.
But PPC32 does not use such registers. */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0beeccd..24725a3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -299,7 +299,7 @@ md5_sha1_test_LDADD = $(libeu)
typeiter_LDADD = $(libdw) $(libelf) $(libmudflap)
low_high_pc_LDADD = $(libdw) $(libelf) $(libmudflap)
test_elf_cntl_gelf_getshdr_LDADD = $(libelf) $(libmudflap)
-backtrace_LDADD = $(libdw) $(libelf) $(libmudflap)
+backtrace_LDADD = $(libdw) $(libelf) $(libmudflap) -lmcheck
backtrace_child_CFLAGS = -fPIE
backtrace_child_LDFLAGS = -pie -pthread
------------------------------------------------------------------------------
it will print many such errors even during 'cd tests; ./backtrace' while no
such errors with the fix below applied.
The backtracer needs to be able to cope with non-essential invalid CFI as at
least PPC has such CFI, which is why this bug has no effect on the testsuite,
unwinder gracefully gives up on interpreting uninitialized memory.
Specifically run-backtrace.sh run has 66 warnings with this fix applied and
1514 without.
Thanks,
Jan
libdw/
2012-10-08 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* cfi.c (execute_cfi) (enough_registers): Clear new memory after
realloc.
diff --git a/libdw/cfi.c b/libdw/cfi.c
index f59f17d..48745ca 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -89,8 +89,11 @@ execute_cfi (Dwarf_CFI *cache,
}
else
{
- bigger->nregs = reg + 1;
fs = bigger;
+ /* Assume reg_unspecified == 0. */
+ memset (fs->regs + fs->nregs, 0,
+ sizeof (*fs->regs) * (reg + 1 - fs->nregs));
+ fs->nregs = reg + 1;
}
}
return true;
11 years, 6 months
[patch] Fix error code from __libdw_find_fde
by Jan Kratochvil
Hi,
__libdw_find_fde may errorneously return DWARF_E_INVALID_DWARF instead of
correct DWARF_E_NO_MATCH.
This is because .eh_frame_hdr contains only starts of ranges covered by FDEs,
not their ends (lengths). Therefore if .eh_frame_hdr returned us some FDE but
that FDE ends before the searched PC that .eh_frame_hdr is not broken.
.eh_frame_hdr is just acceleration, not authoritative information, only
.eh_frame is authoritative what it does and what it does not cover.
Testcase for this patch is the whole testsuite of:
[API RFC] unwinder
https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/0026...
where without -> with this fix on x86_64:
$ cd tests; ./backtrace; echo $?
# 3 0x7f8ce6f56959 - 1 _start
No DWARF information found
1
->
[...]
# 3 0x7f18eae6c959 - 1 _start
0
("No DWARF information found" is not the real error code from .eh_frame_hdr,
it got translated into a different code from the DWARF unwinder.)
Thanks,
Jan
libdw/
2012-10-08 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* fde.c (__libdw_find_fde): Return DWARF_E_NO_MATCH if .eh_frame_hdr
points to FDE which is too short for searched PC.
diff --git a/libdw/fde.c b/libdw/fde.c
index bde0c99..f619912 100644
--- a/libdw/fde.c
+++ b/libdw/fde.c
@@ -231,11 +231,15 @@ __libdw_find_fde (Dwarf_CFI *cache, Dwarf_Addr address)
struct dwarf_fde *fde = __libdw_fde_by_offset (cache, offset);
if (unlikely (fde != NULL)
/* Sanity check the address range. */
- && unlikely (address < fde->start || address >= fde->end))
+ && unlikely (address < fde->start))
{
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return NULL;
}
+ if (unlikely (fde != NULL)
+ /* .eh_frame_hdr does not indicate length covered by FDE. */
+ && unlikely (address >= fde->end))
+ goto no_match;
return fde;
}
11 years, 6 months
[patch] Fix DW_CFA_expression & co. CFA initial push
by Jan Kratochvil
Hi,
DW_CFA_expression / DW_CFA_val_expression expect CFA to be pushed first on the
DWARF stack. This is what CFAP parameter of __libdw_intern_expression says.
But it did not work.
Testcase for this patch is the whole testsuite of:
[API RFC] unwinder
https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/0026...
$ ./backtrace
[...]
# 1 0x7fc399f48a75 - 1 sigusr2
# 2 0x7fc399786300 - 1 (null)
unknown error
->
[...]
# 1 0x7fb29b7fda75 - 1 sigusr2
# 2 0x7fb29b03b300 __restore_rt
# 3 0x7fb29b7fda7b jmp
[...]
Thanks,
Jan
libdw/
2012-10-08 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* dwarf_getlocation.c (__libdw_intern_expression) <cfap>: Fix the
produced bytecode.
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index dfaa742..6ab7023 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -459,7 +459,6 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
if (cfap)
{
/* Synthesize the operation to push the CFA before the expression. */
- --n;
result[0].atom = DW_OP_call_frame_cfa;
result[0].number = 0;
result[0].number2 = 0;
@@ -480,7 +479,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
loclist = loclist->next;
}
- while (n > 0);
+ while (n > (cfap ? 1U : 0U));
/* Insert a record in the search tree so that we can find it again later. */
struct loc_s *newp;
11 years, 6 months
[patch] Code cleanup: Simplify binary_search_fde
by Jan Kratochvil
Hi,
this change has no effect on functionality, it just makes the code less magic.
Thanks,
Jan
libdw/
2012-10-08 Jan Kratochvil <jan.kratochvil(a)redhat.com>
Code cleanup.
* fde.c (binary_search_fde): Remove always true <address >= start>
conditional. Move L initialization upwards.
diff --git a/libdw/fde.c b/libdw/fde.c
index d366768..bde0c99 100644
--- a/libdw/fde.c
+++ b/libdw/fde.c
@@ -181,32 +181,30 @@ binary_search_fde (Dwarf_CFI *cache, Dwarf_Addr address)
u = idx;
else
{
+ l = idx + 1;
+
Dwarf_Addr fde;
if (unlikely (read_encoded_value (&dummy_cfi,
cache->search_table_encoding, &p,
&fde)))
break;
- if (address >= start)
+
+ /* If this is the last entry, its upper bound is assumed to be
+ the end of the module.
+ XXX really should be end of containing PT_LOAD segment */
+ if (l < cache->search_table_entries)
{
- l = idx + 1;
-
- /* If this is the last entry, its upper bound is assumed to be
- the end of the module.
- XXX really should be end of containing PT_LOAD segment */
- if (l < cache->search_table_entries)
- {
- /* Look at the start address in the following entry. */
- Dwarf_Addr end;
- if (unlikely (read_encoded_value
- (&dummy_cfi, cache->search_table_encoding, &p,
- &end)))
- break;
- if (address >= end)
- continue;
- }
-
- return fde - cache->frame_vaddr;
+ /* Look at the start address in the following entry. */
+ Dwarf_Addr end;
+ if (unlikely (read_encoded_value
+ (&dummy_cfi, cache->search_table_encoding, &p,
+ &end)))
+ break;
+ if (address >= end)
+ continue;
}
+
+ return fde - cache->frame_vaddr;
}
}
11 years, 6 months