mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-09-30 02:19:31 +02:00
(unw_step): Also print IP as part of the function-trace.
2004/11/23 12:49:54-08:00 mostang.com!davidm (unw_step): If dwarf_step() fails on a signal-frame, fill in the save-locations for everything that gets saved in the sigcontext structure. 2004/10/25 17:43:57+02:00 homeip.net!davidm Add Debug statement for return-value. (Logical change 1.290)
This commit is contained in:
parent
93599dc278
commit
fa0828ac7d
1 changed files with 49 additions and 19 deletions
|
@ -1,5 +1,5 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2002-2003 Hewlett-Packard Co
|
||||
Copyright (C) 2002-2004 Hewlett-Packard Co
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of libunwind.
|
||||
|
@ -32,13 +32,16 @@ unw_step (unw_cursor_t *cursor)
|
|||
struct cursor *c = (struct cursor *) cursor;
|
||||
int ret, i;
|
||||
|
||||
Debug (1, "(cursor=%p)\n", c);
|
||||
Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);
|
||||
|
||||
/* Try DWARF-based unwinding... */
|
||||
ret = dwarf_step (&c->dwarf);
|
||||
|
||||
if (unlikely (ret == -UNW_ESTOPUNWIND))
|
||||
return ret;
|
||||
if (ret < 0 && ret != -UNW_ENOINFO)
|
||||
{
|
||||
Debug (2, "returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (unlikely (ret < 0))
|
||||
{
|
||||
|
@ -57,7 +60,7 @@ unw_step (unw_cursor_t *cursor)
|
|||
followed by a struct sigcontext. With SA_SIGINFO, the
|
||||
arguments consist a signal number, a siginfo *, and a
|
||||
ucontext *. */
|
||||
unw_word_t sigcontext_addr;
|
||||
unw_word_t sc_addr;
|
||||
unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4;
|
||||
unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8;
|
||||
unw_word_t siginfo_ptr, sigcontext_ptr;
|
||||
|
@ -68,7 +71,10 @@ unw_step (unw_cursor_t *cursor)
|
|||
ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr)
|
||||
| dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr));
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
{
|
||||
Debug (2, "returning 0\n");
|
||||
return 0;
|
||||
}
|
||||
if (siginfo_ptr < c->dwarf.cfa
|
||||
|| siginfo_ptr > c->dwarf.cfa + 256
|
||||
|| sigcontext_ptr < c->dwarf.cfa
|
||||
|
@ -76,7 +82,7 @@ unw_step (unw_cursor_t *cursor)
|
|||
{
|
||||
/* Not plausible for SA_SIGINFO signal */
|
||||
c->sigcontext_format = X86_SCF_LINUX_SIGFRAME;
|
||||
c->sigcontext_addr = sigcontext_addr = c->dwarf.cfa + 4;
|
||||
c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -87,20 +93,37 @@ unw_step (unw_cursor_t *cursor)
|
|||
up here. */
|
||||
c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME;
|
||||
c->sigcontext_addr = sigcontext_ptr;
|
||||
sigcontext_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
|
||||
sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
|
||||
}
|
||||
esp_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_ESP_OFF, 0);
|
||||
ebp_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_EBP_OFF, 0);
|
||||
eip_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_EIP_OFF, 0);
|
||||
esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);
|
||||
ebp_loc = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
|
||||
eip_loc = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0);
|
||||
ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
{
|
||||
Debug (2, "returning 0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0);
|
||||
c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0);
|
||||
c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0);
|
||||
c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0);
|
||||
c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
|
||||
c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0);
|
||||
c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0);
|
||||
c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
|
||||
c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
|
||||
c->dwarf.loc[ST0] = DWARF_NULL_LOC;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
{
|
||||
Debug (2, "returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]),
|
||||
c->dwarf.cfa);
|
||||
|
@ -108,11 +131,13 @@ unw_step (unw_cursor_t *cursor)
|
|||
ebp_loc = DWARF_LOC (c->dwarf.cfa, 0);
|
||||
eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0);
|
||||
c->dwarf.cfa += 8;
|
||||
|
||||
/* Mark all registers unsaved, since we don't know where
|
||||
they are saved (if at all), except for the EBP and
|
||||
EIP. */
|
||||
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
||||
c->dwarf.loc[i] = DWARF_NULL_LOC;
|
||||
}
|
||||
/* Mark all registers unsaved, since we don't know where they
|
||||
are saved (if at all), except for the EBP and EIP. */
|
||||
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
||||
c->dwarf.loc[i] = DWARF_NULL_LOC;
|
||||
c->dwarf.loc[EBP] = ebp_loc;
|
||||
c->dwarf.loc[EIP] = eip_loc;
|
||||
c->dwarf.ret_addr_column = EIP;
|
||||
|
@ -121,10 +146,15 @@ unw_step (unw_cursor_t *cursor)
|
|||
{
|
||||
ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
{
|
||||
Debug (2, "returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
c->dwarf.ip = 0;
|
||||
}
|
||||
return (c->dwarf.ip == 0) ? 0 : 1;
|
||||
ret = (c->dwarf.ip == 0) ? 0 : 1;
|
||||
Debug (2, "returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue