1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-30 23:03:43 +01:00
libunwind-eh_elf/doc/libunwind.man

493 lines
14 KiB
Groff
Raw Normal View History

2003-01-17 08:48:52 +01:00
'\" t
2003-04-01 09:19:34 +02:00
.\" Manual page created with latex2man on Mon Mar 31 14:18:01 PST 2003
2003-01-17 08:48:52 +01:00
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
.nf
..
.de Ve
.ft R
.fi
..
2003-04-01 09:19:34 +02:00
.TH "LIBUNWIND" "3" "31 March 2003" "Programming Library " "Programming Library "
2003-01-17 08:48:52 +01:00
.SH NAME
2003-04-01 09:19:34 +02:00
libunwind
\-\- a (mostly) platform\-independent unwind API
2003-01-17 08:48:52 +01:00
.PP
.SH SYNOPSIS
.PP
#include <libunwind.h>
.br
.PP
int
unw_getcontext(unw_context_t *);
.br
int
unw_init_local(unw_cursor_t *,
unw_context_t *);
.br
int
unw_init_remote(unw_cursor_t *,
unw_addr_space_t,
void *);
.br
int
unw_step(unw_cursor_t *);
.br
int
unw_get_reg(unw_cursor_t *,
2003-03-20 08:51:37 +01:00
unw_regnum_t,
2003-01-17 08:48:52 +01:00
unw_word_t *);
.br
int
unw_get_fpreg(unw_cursor_t *,
2003-03-20 08:51:37 +01:00
unw_regnum_t,
2003-01-17 08:48:52 +01:00
unw_fpreg_t *);
.br
int
unw_set_reg(unw_cursor_t *,
2003-03-20 08:51:37 +01:00
unw_regnum_t,
2003-01-17 08:48:52 +01:00
unw_word_t);
.br
int
2003-01-18 09:10:40 +01:00
unw_set_fpreg(unw_cursor_t *,
2003-03-20 08:51:37 +01:00
unw_regnum_t,
2003-01-17 08:48:52 +01:00
unw_fpreg_t);
.br
int
unw_resume(unw_cursor_t *);
.br
.PP
unw_addr_space_t
2003-03-11 02:05:47 +01:00
unw_local_addr_space;
2003-01-17 08:48:52 +01:00
.br
unw_addr_space_t
unw_create_addr_space(unw_accessors_t,
int);
.br
void
unw_destroy_addr_space(unw_addr_space_t);
.br
unw_accessors_t
unw_get_accessors(unw_addr_space_t);
.br
void
unw_flush_cache(unw_addr_space_t,
unw_word_t,
unw_word_t);
.br
int
unw_set_caching_policy(unw_addr_space_t,
unw_caching_policy_t);
.br
.PP
2003-03-13 03:15:01 +01:00
const char *unw_regname(unw_regnum_t);
2003-01-17 08:48:52 +01:00
.br
int
unw_get_proc_info(unw_cursor_t *,
unw_proc_info_t *);
.br
int
unw_get_save_loc(unw_cursor_t *,
int,
unw_save_loc_t *);
.br
int
2003-03-20 08:51:37 +01:00
unw_is_fpreg(unw_regnum_t);
.br
int
2003-01-17 08:48:52 +01:00
unw_is_signal_frame(unw_cursor_t *);
.br
int
unw_get_proc_name(unw_cursor_t *,
char *,
2003-02-08 11:10:59 +01:00
size_t,
unw_word_t *);
2003-01-17 08:48:52 +01:00
.br
.PP
void
_U_dyn_register(unw_dyn_info_t *);
.br
void
_U_dyn_cancel(unw_dyn_info_t *);
.br
.PP
.SH LOCAL UNWINDING
.PP
Libunwind
is very easy to use when unwinding a stack from
within a running program. This is called \fIlocal\fP
unwinding. Say
you want to unwind the stack while executing in some function
F().
In this function, you would call unw_getcontext()
to get a snapshot of the CPU registers (machine\-state). Then you
initialize an \fIunwind cursor\fP
based on this snapshot. This is
done with a call to unw_init_local().
The cursor now points
to the current frame, that is, the stack frame that corresponds to the
current activation of function F().
The unwind cursor can then
be moved ``up\&'' (towards earlier stack frames) by calling
unw_step().
By repeatedly calling this routine, you can
uncover the entire call\-chain that led to the activation of function
F().
A positive return value from unw_step()
indicates
that there are more frames in the chain, zero indicates that the end
of the chain has been reached, and any negative value indicates that
some sort of error has occurred.
.PP
While it is not possible to directly move the unwind cursor in the
``down\&'' direction (towards newer stack frames), this effect can be
achieved by making copyies of an unwind cursor. For example, a
program that sometimes has to move ``down\&'' by one stack frame could
maintain two cursor variables: ``curr\&''
and ``prev\&''\&.
The
former would be used as the current cursor and prev
would be
maintained as the ``previous frame\&'' cursor by copying the contents of
curr
to prev
right before calling unw_step().
With this approach, the program could move one step ``down\&'' simply by
copying back prev
to curr
whenever that is necessary. In
the mosts extreme case, a program could maintain a separate cursor for
each call frame and that way it could move up and down the call frame
chain at will.
.PP
Given an unwind cursor, it is possible to read and write the CPU
registers that were preserved for the current stack frame identified
by the cursor. Libunwind
provides several routines for this
purpose: unw_get_reg()
reads an integer (general) register,
unw_get_fpreg()
reads a floating\-point register,
unw_set_reg()
writes an integer register, and
unw_set_fpreg()
writes a floating\-point register. Note that,
by definition, only the \fIpreserved\fP
machine state can be accessed
during an unwind operation. Normally, this state consists of the
\fIcallee\-saved\fP
(``preserved\&'') registers. However, in some
special circumstances (e.g., in a signal handler trampoline), even the
\fIcaller\-saved\fP
(``scratch\&'') registers are preserved in the stack
frame and, in those cases, libunwind
will grant access to them
as well. The exact set of registers that can be accessed via the
cursor depends, of course, on the platform. However, there are two
registers that can be read on all platforms: the instruction pointer
(IP), sometimes also known as the ``program counter\&'', and the stack
pointer (SP). In libunwind,
these registers are identified by
the macros UNW_REG_IP
and UNW_REG_SP,
respectively.
.PP
Besides just moving the unwind cursor and reading/writing saved
registers, libunwind
also provides the ability to resume
execution at an arbitrary stack frame. As you might guess, this is
useful for implementing non\-local gotos and the exception handling
needed by some high\-level languages such as Java. Resuming execution
with a particular stack frame simply requires calling
unw_resume()
and passing the cursor identifying the target
frame as the only argument.
.PP
Normally, libunwind
supports both local and remote unwinding
(the latter will be explained in the next section). However, if you
tell libunwind that your program only needs local unwinding, then a
special implementation can be selected which may run much faster than
the generic implementation which supports both kinds of unwinding. To
select this optimized version, simply define the macro
UNW_LOCAL_ONLY
before including the headerfile
<libunwind.h>\&.
If is perfectly OK for a single program to
employ both local\-only and generic unwinding. That is, whether or not
UNW_LOCAL_ONLY
is defined is a choice that each source\-file
(compilation\-unit) can make on its own. Independent of the setting(s)
of UNW_LOCAL_ONLY,
you\&'ll always link the same library into
the program (normally \fB\-l\fPunwind).
.PP
If we put all of the above together, here is how we could use
libunwind
write function show_backtrace()
which prints
a classic stack trace:
.PP
.Vb
#define UNW_LOCAL_ONLY
#include <libunwind.h>
void show_backtrace (void) {
unw_cursor_t cursor; unw_context_t uc;
unw_word_t ip, sp;
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
while (unw_step(&cursor) > 0) {
unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);
printf ("ip = 0, sp = 0\\n", (long) ip, (long) sp);
}
}
.Ve
.PP
.SH REMOTE UNWINDING
.PP
Libunwind
can also be used to unwind a stack in a ``remote\&''
process. Here, ``remote\&'' may mean another process on the same
machine or even a process on a completely different machine from the
one that is running libunwind\&.
Remote unwinding is typically
used by debuggers and instruction\-set simulators, for example.
.PP
Before you can unwind a remote process, you need to create a new
address\-space object for that process. This is achieved with the
unw_create_addr_space
routine. The routine takes two
arguments: a pointer to a set of \fIaccessor\fP
routines and an
integer that specifies the byte\-order of the target process. The
accessor routines provide libunwind
with the means to
communicate with the remote process. In particular, there are
callbacks to read and write the process\&'s memory, its registers, and
to access unwind information which may be needed by libunwind\&.
.PP
With the address space created, unwinding can be initiated by a call
to unw_init_remote().
This routine is very similar to
unw_init_local(),
except that it takes an address\-space
object and an opaque pointer as arguments. The routine uses these
arguments to fetch the initial machine state. Libunwind
never
uses the opaque pointer on its own, but instead justs passes it on to
the accessor (callback) routines. Typically, this pointer is used to
select, e.g., the thread within a process that is to be unwound.
.PP
Once a cursor has been initialized with unw_init_remote(),
unwinding works exactly like in the local case. That is, you can use
unw_step
to move ``up\&'' in the call\-chain, read and write
registers, or resume execution at a particular stack frame by calling
unw_resume\&.
.PP
.SH CROSS\-PLATFORM AND MULTI\-PLATFORM UNWINDING
.PP
Libunwind
has been designed to enable unwinding across
platforms (architectures). Indeed, a single program can use
libunwind
to unwind an arbitrary number of target platforms,
all at the same time!
.PP
We call the machine that is running libunwind
the \fIhost\fP
and the machine that is running the process being unwound the
\fItarget\fP\&.
If the host and the target platform are the same, we
call it \fInative\fP
unwinding. If they differ, we call it
\fIcross\-platform\fP
unwinding.
.PP
The principle behind supporting native, cross\-platform, and
multi\-platform unwinding are very simple: for native unwinding, a
program includes <libunwind.h>
and uses the linker switch
\fB\-l\fPunwind\&.
For cross\-platform unwinding, a program
includes <libunwind\-PLAT\&.h>
and uses the linker
switch \fB\-l\fPunwind\-PLAT,
where PLAT
is the name
of the target platform (e.g., ia64
for IA\-64, hppa\-elf
for ELF\-based HP PA\-RISC, or x86
for 80386). Multi\-platform
unwinding works exactly like cross\-platform unwinding, the only
limitation is that a single source file (compilation unit) can include
at most one libunwind
header file. In other words, the
platform\-specific support for each supported target needs to be
isolated in separate source files\-\-\-a limitation that shouldn\&'t be an
issue in practice.
.PP
Note that, by definition, local unwinding is possible only for the
native case. Attempting to call, e.g., unw_local_init()
when
targeting a cross\-platform will result in a link\-time error
(unresolved references).
.PP
.SH THREAD\- AND SIGNAL\-SAFETY
.PP
All libunwind
routines are thread\-safe. What this means is
that multiple threads may use libunwind
simulatenously.
However, any given cursor may be accessed by only one thread at
any given time.
.PP
To ensure thread\-safety, some libunwind
routines may have to
use locking. Such routines \fImust not\fP
be called from signal
handlers (directly or indirectly) and are therefore \fInot\fP
signal\-safe. The manual page for each libunwind
routine
identifies whether or not it is signal\-safe, but as a general rule,
any routine that may be needed for \fIlocal\fP
unwinding is
signal\-safe (e.g., unw_step()
for local unwinding is
signal\-safe). For remote\-unwinding, \fInone\fP
of the
libunwind
routines are guaranteed to be signal\-safe.
.PP
.SH UNWINDING THROUGH DYNAMICALLY GENERATED CODE
.PP
Libunwind
provides the routines _U_dyn_register()
and
_U_dyn_cancel
to register/cancel the information required to
unwind through code that has been generated at runtime (e.g., by a
just\-in\-time (JIT) compiler). It is important to register the
information for \fIall\fP
dynamically generated code because
otherwise, a debugger may not be able to function properly or
high\-level language exception handling may not work as expected.
.PP
The interface for registering and canceling dynamic unwind info has
been designed for maximum efficiency, so as to minimize the
performance impact on JIT\-compilers. In particular, both routines are
guaranteed to execute in ``constant time\&'' (O(1)) and the
data\-structure encapsulating the dynamic unwind info has been designed
to facilitate sharing, such that similar procedures can share much of
the underlying information.
.PP
.SH CACHING OF UNWIND INFO
.PP
To speed up execution, libunwind
may aggressively cache the
information it needs to perform unwinding. If a process changes
during its lifetime, this creates a risk of libunwind
using
stale data. For example, this would happen if libunwind
were
to cache information about a shared library which later on gets
unloaded (e.g., via \fIdlclose\fP(3)).
.PP
To prevent the risk of using stale data, libunwind
provides two
facilities: first, it is possible to flush the cached information
associated with a specific address range in the target process (or the
entire address space, if desired). This functionality is provided by
unw_flush_cache().
The second facility is provided by
unw_set_caching_policy(),
which lets a program
select the exact caching policy in use for a given address\-space
object. In particular, by selecting the policy
UNW_CACHE_NONE,
it is possible to turn off caching
completely, therefore eliminating the risk of stale data alltogether
(at the cost of slower execution). By default, caching is enabled for
local unwinding only.
.PP
.SH FILES
.PP
.TP
libunwind.h
Headerfile to include for native (same
platform) unwinding.
.TP
libunwind\-PLAT\&.h
Headerfile to include when
unwind target runs on platform PLAT\&.
For example, to unwind
an IA\-64 program, the header file libunwind\-ia64.h
should be
included.
.TP
\fB\-l\fPunwind
Linker\-switch to add when building a
program that does native (same platform) unwinding.
.TP
\fB\-l\fPunwind\-PLAT
Linker\-switch to add when
building a program that unwinds a program on platform PLAT\&.
For example, to (cross\-)unwind an IA\-64 program, the linker switch
\-lunwind\-ia64
should be added. Note: multiple such switches
2003-03-27 05:29:07 +01:00
may need to be specified for programs that can unwind programs on
2003-01-17 08:48:52 +01:00
multiple platforms.
.PP
.SH SEE ALSO
.PP
2003-02-08 11:10:59 +01:00
libunwind\-ia64(3),
libunwind\-ptrace(3),
libunwind\-setjmp(3),
2003-03-20 08:51:37 +01:00
unw_create_addr_space(3),
unw_destroy_addr_space(3),
unw_flush_cache(3),
unw_get_accessors(3),
unw_get_fpreg(3),
unw_get_proc_info(3),
unw_get_proc_name(3),
unw_get_reg(3),
unw_getcontext(3),
unw_init_local(3),
unw_init_remote(3),
unw_is_fpreg(3),
unw_is_signal_frame(3),
unw_regname(3),
unw_resume(3),
unw_set_caching_policy(3),
unw_set_fpreg(3),
unw_set_reg(3),
unw_step(3)
2003-01-17 08:48:52 +01:00
.PP
.SH AUTHOR
.PP
David Mosberger\-Tang
.br
Hewlett\-Packard Labs
.br
Palo\-Alto, CA 94304
.br
Email: \fBdavidm@hpl.hp.com\fP
.br
WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.