diff --git a/doc/common.tex.in b/doc/common.tex.in index e69de29b..2ff94fdd 100644 --- a/doc/common.tex.in +++ b/doc/common.tex.in @@ -0,0 +1,8 @@ +\setVersion{@VERSION@} + +\newcommand{\Lt}{\symbol{"3C}} +\newcommand{\Gt}{\symbol{"3E}} +\newcommand{\Type}[1]{\File{#1}} % see libunwind.trans +\newcommand{\Func}[1]{\Prog{#1}} % see libunwind.trans +\newcommand{\Var}[1]{\Prog{#1}} % see libunwind.trans +\newcommand{\Const}[1]{\File{#1}} % see libunwind.trans diff --git a/doc/libunwind.man b/doc/libunwind.man index e69de29b..5bcb0ade 100644 --- a/doc/libunwind.man +++ b/doc/libunwind.man @@ -0,0 +1,469 @@ +'\" t +.\" Manual page created with latex2man on Thu Jan 16 23:17:13 PST 2003 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "LIBUNWIND" "3" "16 January 2003" "Programming Library " "Programming Library " +.SH NAME + +.PP +libunwind \-\- a (mostly) platform\-independent unwind API +.PP +.SH SYNOPSIS + +.PP +#include +.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 *, +int, +unw_word_t *); +.br +int +unw_get_fpreg(unw_cursor_t *, +int, +unw_fpreg_t *); +.br +int +unw_set_reg(unw_cursor_t *, +int, +unw_word_t); +.br +int +unw_get_fpreg(unw_cursor_t *, +int, +unw_fpreg_t); +.br +int +unw_resume(unw_cursor_t *); +.br +.PP +unw_addr_space_t +local_addr_space; +.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 +const char *unw_regname(int); +.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 +unw_is_signal_frame(unw_cursor_t *); +.br +int +unw_get_proc_name(unw_cursor_t *, +char *, +size_t); +.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 +\&. +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 + +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 +and uses the linker switch +\fB\-l\fPunwind\&. +For cross\-platform unwinding, a program +includes +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 +may need to be specified for programs that can unwind programss on +multiple platforms. +.PP +.SH SEE ALSO + +.PP +libunwind\-ia64(3), libunwind\-hppa(3), libunwind\-x86(3), +unw_init_local(3), unw_init_remote(3), etc. +.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. diff --git a/doc/libunwind.tex b/doc/libunwind.tex index e69de29b..ed67d7a0 100644 --- a/doc/libunwind.tex +++ b/doc/libunwind.tex @@ -0,0 +1,328 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3}{libunwind}{David Mosberger-Tang}{Programming Library}{Introduction to libunwind} + + libunwind -- a (mostly) platform-independent unwind API +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind.h$>$}\\ + +\noindent +\Type{int} \Func{unw\_getcontext}(\Type{unw\_context\_t~*});\\ +\noindent +\Type{int} \Func{unw\_init\_local}(\Type{unw\_cursor\_t~*}, \Type{unw\_context\_t~*});\\ +\noindent +\Type{int} \Func{unw\_init\_remote}(\Type{unw\_cursor\_t~*}, \Type{unw\_addr\_space\_t}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_step}(\Type{unw\_cursor\_t~*});\\ +\noindent +\Type{int} \Func{unw\_get\_reg}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_word\_t~*});\\ +\noindent +\Type{int} \Func{unw\_get\_fpreg}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_fpreg\_t~*});\\ +\noindent +\Type{int} \Func{unw\_set\_reg}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_word\_t});\\ +\noindent +\Type{int} \Func{unw\_get\_fpreg}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_fpreg\_t});\\ +\noindent +\Type{int} \Func{unw\_resume}(\Type{unw\_cursor\_t~*});\\ + +\noindent +\Type{unw\_addr\_space\_t} \Var{local\_addr\_space};\\ +\noindent +\Type{unw\_addr\_space\_t} \Func{unw\_create\_addr\_space}(\Type{unw\_accessors\_t}, \Type{int});\\ +\noindent +\Type{void} \Func{unw\_destroy\_addr\_space}(\Type{unw\_addr\_space\_t});\\ +\noindent +\Type{unw\_accessors\_t} \Func{unw\_get\_accessors}(\Type{unw\_addr\_space\_t});\\ +\noindent +\Type{void} \Func{unw\_flush\_cache}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t});\\ +\noindent +\Type{int} \Func{unw\_set\_caching\_policy}(\Type{unw\_addr\_space\_t}, \Type{unw\_caching\_policy\_t});\\ + +\noindent +\Type{const char *}\Func{unw\_regname}(\Type{int});\\ +\noindent +\Type{int} \Func{unw\_get\_proc\_info}(\Type{unw\_cursor\_t~*}, \Type{unw\_proc\_info\_t~*});\\ +\noindent +\Type{int} \Func{unw\_get\_save\_loc}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_save\_loc\_t~*});\\ +\noindent +\Type{int} \Func{unw\_is\_signal\_frame}(\Type{unw\_cursor\_t~*});\\ +\noindent +\Type{int} \Func{unw\_get\_proc\_name}(\Type{unw\_cursor\_t~*}, \Type{char~*}, \Type{size\_t});\\ + +\noindent +\Type{void} \Func{\_U\_dyn\_register}(\Type{unw\_dyn\_info\_t~*});\\ +\noindent +\Type{void} \Func{\_U\_dyn\_cancel}(\Type{unw\_dyn\_info\_t~*});\\ + +\section{Local Unwinding} + +\Prog{Libunwind} is very easy to use when unwinding a stack from +within a running program. This is called \emph{local} unwinding. Say +you want to unwind the stack while executing in some function +\Func{F}(). In this function, you would call \Func{unw\_getcontext}() +to get a snapshot of the CPU registers (machine-state). Then you +initialize an \emph{unwind~cursor} based on this snapshot. This is +done with a call to \Func{unw\_init\_local}(). The cursor now points +to the current frame, that is, the stack frame that corresponds to the +current activation of function \Func{F}(). The unwind cursor can then +be moved ``up'' (towards earlier stack frames) by calling +\Func{unw\_step}(). By repeatedly calling this routine, you can +uncover the entire call-chain that led to the activation of function +\Func{F}(). A positive return value from \Func{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. + +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: ``\Var{curr}'' and ``\Var{prev}''. The +former would be used as the current cursor and \Var{prev} would be +maintained as the ``previous frame'' cursor by copying the contents of +\Var{curr} to \Var{prev} right before calling \Func{unw\_step}(). +With this approach, the program could move one step ``down'' simply by +copying back \Var{prev} to \Var{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. + +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. \Prog{Libunwind} provides several routines for this +purpose: \Func{unw\_get\_reg}() reads an integer (general) register, +\Func{unw\_get\_fpreg}() reads a floating-point register, +\Func{unw\_set\_reg}() writes an integer register, and +\Func{unw\_set\_fpreg}() writes a floating-point register. Note that, +by definition, only the \emph{preserved} machine state can be accessed +during an unwind operation. Normally, this state consists of the +\emph{callee-saved} (``preserved'') registers. However, in some +special circumstances (e.g., in a signal handler trampoline), even the +\emph{caller-saved} (``scratch'') registers are preserved in the stack +frame and, in those cases, \Prog{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 \Prog{libunwind}, these registers are identified by +the macros \Const{UNW\_REG\_IP} and \Const{UNW\_REG\_SP}, +respectively. + +Besides just moving the unwind cursor and reading/writing saved +registers, \Prog{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 +\Func{unw\_resume}() and passing the cursor identifying the target +frame as the only argument. + +Normally, \Prog{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 +\Const{UNW\_LOCAL\_ONLY} before including the headerfile +\File{$<$libunwind.h$>$}. If is perfectly OK for a single program to +employ both local-only and generic unwinding. That is, whether or not +\Const{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 \Const{UNW\_LOCAL\_ONLY}, you'll always link the same library into +the program (normally \Opt{-l}\File{unwind}). + +If we put all of the above together, here is how we could use +\Prog{libunwind} write function \Func{show\_backtrace}() which prints +a classic stack trace: + +\begin{verbatim} +#define UNW_LOCAL_ONLY +#include + +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 = %lx, sp = %lx\n", (long) ip, (long) sp); + } +} +\end{verbatim} + + +\section{Remote Unwinding} + +\Prog{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 \Prog{libunwind}. Remote unwinding is typically +used by debuggers and instruction-set simulators, for example. + +Before you can unwind a remote process, you need to create a new +address-space object for that process. This is achieved with the +\Func{unw\_create\_addr\_space} routine. The routine takes two +arguments: a pointer to a set of \emph{accessor} routines and an +integer that specifies the byte-order of the target process. The +accessor routines provide \Func{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 \Func{libunwind}. + +With the address space created, unwinding can be initiated by a call +to \Func{unw\_init\_remote}(). This routine is very similar to +\Func{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. \Prog{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. + +Once a cursor has been initialized with \Func{unw\_init\_remote}(), +unwinding works exactly like in the local case. That is, you can use +\Func{unw\_step} to move ``up'' in the call-chain, read and write +registers, or resume execution at a particular stack frame by calling +\Func{unw\_resume}. + + +\section{Cross-platform and Multi-platform Unwinding} + +\Prog{Libunwind} has been designed to enable unwinding across +platforms (architectures). Indeed, a single program can use +\Prog{libunwind} to unwind an arbitrary number of target platforms, +all at the same time! + +We call the machine that is running \Prog{libunwind} the \emph{host} +and the machine that is running the process being unwound the +\emph{target}. If the host and the target platform are the same, we +call it \emph{native} unwinding. If they differ, we call it +\emph{cross-platform} unwinding. + +The principle behind supporting native, cross-platform, and +multi-platform unwinding are very simple: for native unwinding, a +program includes \File{$<$libunwind.h$>$} and uses the linker switch +\Opt{-l}\File{unwind}. For cross-platform unwinding, a program +includes \File{$<$libunwind-}\Var{PLAT}\File{.h$>$} and uses the linker +switch \Opt{-l}\File{unwind-}\Var{PLAT}, where \Var{PLAT} is the name +of the target platform (e.g., \File{ia64} for IA-64, \File{hppa-elf} +for ELF-based HP PA-RISC, or \File{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 \Prog{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. + +Note that, by definition, local unwinding is possible only for the +native case. Attempting to call, e.g., \Func{unw\_local\_init}() when +targeting a cross-platform will result in a link-time error +(unresolved references). + + +\section{Thread- and Signal-Safety} + + +All \Prog{libunwind} routines are thread-safe. What this means is +that multiple threads may use \Prog{libunwind} simulatenously. +However, any given cursor may be accessed by only one thread at +any given time. + +To ensure thread-safety, some \Prog{libunwind} routines may have to +use locking. Such routines \emph{must~not} be called from signal +handlers (directly or indirectly) and are therefore \emph{not} +signal-safe. The manual page for each \Prog{libunwind} routine +identifies whether or not it is signal-safe, but as a general rule, +any routine that may be needed for \emph{local} unwinding is +signal-safe (e.g., \Func{unw\_step}() for local unwinding is +signal-safe). For remote-unwinding, \emph{none} of the +\Prog{libunwind} routines are guaranteed to be signal-safe. + + +\section{Unwinding Through Dynamically Generated Code} + +\Func{Libunwind} provides the routines \Func{\_U\_dyn\_register}() and +\Func{\_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 \emph{all} 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. + +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. + + +\section{Caching of Unwind Info} + +To speed up execution, \Prog{libunwind} may aggressively cache the +information it needs to perform unwinding. If a process changes +during its lifetime, this creates a risk of \Prog{libunwind} using +stale data. For example, this would happen if \Prog{libunwind} were +to cache information about a shared library which later on gets +unloaded (e.g., via \Cmd{dlclose}{3}). + +To prevent the risk of using stale data, \Prog{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 +\Func{unw\_flush\_cache}(). The second facility is provided by +\Func{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 +\Const{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. + + +\section{Files} + +\begin{Description} +\item[\File{libunwind.h}] Headerfile to include for native (same + platform) unwinding. +\item[\File{libunwind-}\Var{PLAT}\File{.h}] Headerfile to include when + unwind target runs on platform \Var{PLAT}. For example, to unwind + an IA-64 program, the header file \File{libunwind-ia64.h} should be + included. +\item[\Opt{-l}\File{unwind}] Linker-switch to add when building a + program that does native (same platform) unwinding. +\item[\Opt{-l}\File{unwind-}\Var{PLAT}] Linker-switch to add when + building a program that unwinds a program on platform \Var{PLAT}. + For example, to (cross-)unwind an IA-64 program, the linker switch + \File{-lunwind-ia64} should be added. Note: multiple such switches + may need to be specified for programs that can unwind programss on + multiple platforms. +\end{Description} + +\section{See Also} + +libunwind-ia64(3), libunwind-hppa(3), libunwind-x86(3), +unw\_init\_local(3), unw\_init\_remote(3), etc. + +\section{Author} + +\noindent +David Mosberger-Tang\\ +Hewlett-Packard Labs\\ +Palo-Alto, CA 94304\\ +Email: \Email{davidm@hpl.hp.com}\\ +WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}. +\LatexManEnd + +\end{document} diff --git a/doc/libunwind.trans b/doc/libunwind.trans index e69de29b..7eb38a9e 100644 --- a/doc/libunwind.trans +++ b/doc/libunwind.trans @@ -0,0 +1,29 @@ +$manMacro1a{'Type'} = $manMacro1a{File}; +$manMacro1b{'Type'} = $manMacro1b{File}; +$htmlMacro1a{'Type'} = $htmlMacro1a{File}; +$htmlMacro1b{'Type'} = $htmlMacro1b{File}; +$texiMacro1a{'Type'} = $texiMacro1a{File}; +$texiMacro1b{'Type'} = $texiMacro1b{File}; +$manMacro1a{'Func'} = $manMacro1a{Prog}; +$manMacro1b{'Func'} = $manMacro1b{Prog}; +$htmlMacro1a{'Func'} = $htmlMacro1a{Arg}; +$htmlMacro1b{'Func'} = $htmlMacro1b{Arg}; +$texiMacro1a{'Func'} = $texiMacro1a{Prog}; +$texiMacro1b{'Func'} = $texiMacro1b{Prog}; +$manMacro1a{'Var'} = $manMacro1a{Prog}; +$manMacro1b{'Var'} = $manMacro1b{Prog}; +$htmlMacro1a{'Var'} = $htmlMacro1a{Prog}; +$htmlMacro1b{'Var'} = $htmlMacro1b{Prog}; +$texiMacro1a{'Var'} = $texiMacro1a{Prog}; +$texiMacro1b{'Var'} = $texiMacro1b{Prog}; +$manMacro1a{'Const'} = $manMacro1a{File}; +$manMacro1b{'Const'} = $manMacro1b{File}; +$htmlMacro1a{'Const'} = $htmlMacro1a{File}; +$htmlMacro1b{'Const'} = $htmlMacro1b{File}; +$texiMacro1a{'Const'} = $texiMacro1a{File}; +$texiMacro1b{'Const'} = $texiMacro1b{File}; + +$htmlMacro1a{'section'} = '\n

'; + $htmlMacro1b{'section'} = '

\n'; +$htmlMacro1a{'subsection'} = '\n

'; + $htmlMacro1b{'subsection'} = '

\n';