mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 07:37:38 +01:00
eh_elf: tolerate slightly out-of-bound mem access
Recover from slightly out-of-bounds wrt. %rsp memory accesses. When we're unwinding the first frame of a chain, and we start from, eg. a `pop %rbx` at the end of the function, the DWARF can be out of sync and still state that eg. `%rbx` is saved at something that simplifies to `%rsp-8`. Which might not be accessibe through the `access_mem` abstraction, eg. if we're running perf and it didn't capture the stack below `%rsp`
This commit is contained in:
parent
cc2d07f550
commit
bba251cf13
1 changed files with 20 additions and 1 deletions
|
@ -39,6 +39,7 @@ void eh_elf_clear() {
|
|||
static struct {
|
||||
struct cursor* cursor;
|
||||
int last_rc;
|
||||
uintptr_t cur_rsp;
|
||||
} _fetch_state;
|
||||
|
||||
static uintptr_t fetchw_here(uintptr_t addr) {
|
||||
|
@ -51,7 +52,24 @@ static uintptr_t fetchw_here(uintptr_t addr) {
|
|||
_fetch_state.cursor->dwarf.as_arg);
|
||||
|
||||
if(rv != 0) {
|
||||
Debug(1, "dwarf_get error %d\n", rv);
|
||||
/*
|
||||
Recover from slightly out-of-sync DWARF
|
||||
====
|
||||
|
||||
When we're unwinding the first frame of a chain, and we start from,
|
||||
eg. a `pop %rbx` at the end of the function, the DWARF can be out
|
||||
of sync and still state that eg. `%rbx` is saved at something that
|
||||
simplifies to `%rsp-8`. Which might not be accessibe through the
|
||||
`access_mem` abstraction, eg. if we're running perf and it didn't
|
||||
capture the stack below `%rsp`
|
||||
*/
|
||||
if(_fetch_state.cur_rsp - addr < 128) {
|
||||
Debug(3, "dwarf_get warning: tried to access %lX (%lX below rsp)\n",
|
||||
addr, _fetch_state.cur_rsp - addr);
|
||||
return 0; // hope that nothing bad will happen.
|
||||
}
|
||||
Debug(1, "dwarf_get error %d (addr %lX, sp %lX)\n",
|
||||
rv, addr, _fetch_state.cur_rsp);
|
||||
_fetch_state.last_rc = rv;
|
||||
}
|
||||
|
||||
|
@ -112,6 +130,7 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
// Set _fetch_state before passing fetchw_here
|
||||
_fetch_state.cursor = cursor;
|
||||
_fetch_state.last_rc = 0;
|
||||
_fetch_state.cur_rsp = cursor->dwarf.cfa;
|
||||
|
||||
Debug(4, "Unwinding in mmap entry %s at position 0x%lx (sp=%016lx)\n",
|
||||
mmap_entry->object_name,
|
||||
|
|
Loading…
Reference in a new issue