mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-02-18 02:51:41 +01:00
Rename: NOTES -> doc/NOTES
}(Logical change 1.7)
This commit is contained in:
parent
be72029dac
commit
bbc09de14d
1 changed files with 0 additions and 74 deletions
74
NOTES
74
NOTES
|
@ -1,74 +0,0 @@
|
||||||
The central data structure of the unwind API is the unwind cursor.
|
|
||||||
This structure tracks the frame registers and the preserved registers.
|
|
||||||
The distinction between frame registers and preserved registers is
|
|
||||||
important: the former represent the *current* value of a register (as
|
|
||||||
it existed at the current IP); the latter represent the *saved* value
|
|
||||||
of a register (i.e., the value that existed on entry to the current
|
|
||||||
procedure). The unwind API defines a handful of well-known frame
|
|
||||||
"registers":
|
|
||||||
|
|
||||||
- ip: the instruction pointer (pc)
|
|
||||||
- rp: the return pointer (rp, aka "return address" or "return link")
|
|
||||||
- sp: the stack pointer (memory stack pointer, in the case of ia64)
|
|
||||||
- fp: the frame pointer
|
|
||||||
- first_ip: the starting address of the current "procedure"
|
|
||||||
- handler: a pointer to an architecture & language-specific
|
|
||||||
"personality" routine
|
|
||||||
- lsda: a pointer to an architecture & language-specific
|
|
||||||
data-area
|
|
||||||
|
|
||||||
The API defines no well-known preserved registers. Each architecture
|
|
||||||
can define additional registers as needed. Of course, a portable
|
|
||||||
application may only rely on well-known registers. The names for
|
|
||||||
preserved registers are defined in the architecture-specific header
|
|
||||||
file <unwind-ARCH.h>. For example, to get the IA-64-specific register
|
|
||||||
names, an application would do:
|
|
||||||
|
|
||||||
#include <unwind-ia64.h>
|
|
||||||
|
|
||||||
The API is designed to handle two primary cases: unwinding within the
|
|
||||||
current (local) process and unwinding of another ("remote") process
|
|
||||||
(e.g., through ptrace()). In the local case, the initial machine
|
|
||||||
state is captured by an unwind context (currently the same as
|
|
||||||
ucontext_t). In the remote case, the initial machine state is
|
|
||||||
captured by an unwind accessor structure, which provides callback
|
|
||||||
routines for reading/writing memory and registers and for obtaining
|
|
||||||
unwind information.
|
|
||||||
|
|
||||||
Once a cursor has been initialized, you can step through the call
|
|
||||||
chain with the unw_step() routine. The frame registers and the
|
|
||||||
preserved state can then be accessed with unw_get_reg() or modified
|
|
||||||
with unw_set_reg(). For floating-point registers, there are separate
|
|
||||||
unw_get_fpreg() and unw_set_fpreg() routines (on some arches, e.g.,
|
|
||||||
Alpha, these could be just aliases for unw_{g,s}et_reg()). The
|
|
||||||
unw_resume() routine can be used to resume execution at an arbitrary
|
|
||||||
point in the call-chain (as identified by an unwind cursor). This is
|
|
||||||
intended for exception handling and, at least for now, the intention
|
|
||||||
is to support this routine only for the local case. Kevin, if you
|
|
||||||
feel gdb could benefit from such a routine, I'd be interested to hear
|
|
||||||
about it.
|
|
||||||
|
|
||||||
Note that it is perfectly legal to make copies of the unwind cursor.
|
|
||||||
This makes it possible, e.g., to obtain an unwind context, modify the
|
|
||||||
state in an earlier call frame, and then resume execution at the point
|
|
||||||
at which the unwind context was captured.
|
|
||||||
|
|
||||||
Here is a quick example of how to use the unwind API to do a simple
|
|
||||||
stack trace:
|
|
||||||
|
|
||||||
unw_cursor_t cursor;
|
|
||||||
unw_word_t ip, sp;
|
|
||||||
ucontext_t uc;
|
|
||||||
|
|
||||||
getcontext(&uc);
|
|
||||||
unw_init_local(&cursor, &uc);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
|
||||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
|
||||||
printf ("ip=%016lx sp=%016lx\n", ip, sp);
|
|
||||||
}
|
|
||||||
while (unw_step (&cursor) > 0);
|
|
||||||
|
|
||||||
Note that this particular example should work on pretty much any
|
|
||||||
architecture, as it doesn't rely on any arch-specific registers.
|
|
Loading…
Add table
Reference in a new issue