mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 1 | \documentclass{article} |
| 2 | \usepackage[fancyhdr,pdf]{latex2man} |
| 3 | |
| 4 | \input{common.tex} |
| 5 | |
| 6 | \begin{document} |
| 7 | |
esiee.fr!m.delahaye | 972aec7 | 2003-03-31 19:57:09 +0000 | [diff] [blame] | 8 | \begin{Name}{3}{libunwind}{David Mosberger-Tang}{Programming Library}{Introduction to libunwind}libunwind -- a (mostly) platform-independent unwind API |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 9 | \end{Name} |
| 10 | |
| 11 | \section{Synopsis} |
| 12 | |
| 13 | \File{\#include $<$libunwind.h$>$}\\ |
| 14 | |
| 15 | \noindent |
| 16 | \Type{int} \Func{unw\_getcontext}(\Type{unw\_context\_t~*});\\ |
| 17 | \noindent |
| 18 | \Type{int} \Func{unw\_init\_local}(\Type{unw\_cursor\_t~*}, \Type{unw\_context\_t~*});\\ |
| 19 | \noindent |
| 20 | \Type{int} \Func{unw\_init\_remote}(\Type{unw\_cursor\_t~*}, \Type{unw\_addr\_space\_t}, \Type{void~*});\\ |
| 21 | \noindent |
| 22 | \Type{int} \Func{unw\_step}(\Type{unw\_cursor\_t~*});\\ |
| 23 | \noindent |
mostang.com!davidm | a21507d | 2003-03-20 07:51:37 +0000 | [diff] [blame] | 24 | \Type{int} \Func{unw\_get\_reg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 25 | \noindent |
mostang.com!davidm | a21507d | 2003-03-20 07:51:37 +0000 | [diff] [blame] | 26 | \Type{int} \Func{unw\_get\_fpreg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 27 | \noindent |
mostang.com!davidm | a21507d | 2003-03-20 07:51:37 +0000 | [diff] [blame] | 28 | \Type{int} \Func{unw\_set\_reg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 29 | \noindent |
mostang.com!davidm | a21507d | 2003-03-20 07:51:37 +0000 | [diff] [blame] | 30 | \Type{int} \Func{unw\_set\_fpreg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 31 | \noindent |
| 32 | \Type{int} \Func{unw\_resume}(\Type{unw\_cursor\_t~*});\\ |
| 33 | |
| 34 | \noindent |
mostang.com!davidm | a494d61 | 2003-03-11 01:05:47 +0000 | [diff] [blame] | 35 | \Type{unw\_addr\_space\_t} \Var{unw\_local\_addr\_space};\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 36 | \noindent |
| 37 | \Type{unw\_addr\_space\_t} \Func{unw\_create\_addr\_space}(\Type{unw\_accessors\_t}, \Type{int});\\ |
| 38 | \noindent |
| 39 | \Type{void} \Func{unw\_destroy\_addr\_space}(\Type{unw\_addr\_space\_t});\\ |
| 40 | \noindent |
| 41 | \Type{unw\_accessors\_t} \Func{unw\_get\_accessors}(\Type{unw\_addr\_space\_t});\\ |
| 42 | \noindent |
| 43 | \Type{void} \Func{unw\_flush\_cache}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t});\\ |
| 44 | \noindent |
| 45 | \Type{int} \Func{unw\_set\_caching\_policy}(\Type{unw\_addr\_space\_t}, \Type{unw\_caching\_policy\_t});\\ |
| 46 | |
| 47 | \noindent |
mostang.com!davidm | 38ec048 | 2003-03-13 02:15:01 +0000 | [diff] [blame] | 48 | \Type{const char *}\Func{unw\_regname}(\Type{unw\_regnum\_t});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 49 | \noindent |
| 50 | \Type{int} \Func{unw\_get\_proc\_info}(\Type{unw\_cursor\_t~*}, \Type{unw\_proc\_info\_t~*});\\ |
| 51 | \noindent |
| 52 | \Type{int} \Func{unw\_get\_save\_loc}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_save\_loc\_t~*});\\ |
| 53 | \noindent |
mostang.com!davidm | a21507d | 2003-03-20 07:51:37 +0000 | [diff] [blame] | 54 | \Type{int} \Func{unw\_is\_fpreg}(\Type{unw\_regnum\_t});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 55 | \Type{int} \Func{unw\_is\_signal\_frame}(\Type{unw\_cursor\_t~*});\\ |
| 56 | \noindent |
mostang.com!davidm | f5892c2 | 2003-02-08 10:10:59 +0000 | [diff] [blame] | 57 | \Type{int} \Func{unw\_get\_proc\_name}(\Type{unw\_cursor\_t~*}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*});\\ |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 58 | |
| 59 | \noindent |
| 60 | \Type{void} \Func{\_U\_dyn\_register}(\Type{unw\_dyn\_info\_t~*});\\ |
| 61 | \noindent |
| 62 | \Type{void} \Func{\_U\_dyn\_cancel}(\Type{unw\_dyn\_info\_t~*});\\ |
| 63 | |
| 64 | \section{Local Unwinding} |
| 65 | |
| 66 | \Prog{Libunwind} is very easy to use when unwinding a stack from |
| 67 | within a running program. This is called \emph{local} unwinding. Say |
| 68 | you want to unwind the stack while executing in some function |
| 69 | \Func{F}(). In this function, you would call \Func{unw\_getcontext}() |
| 70 | to get a snapshot of the CPU registers (machine-state). Then you |
| 71 | initialize an \emph{unwind~cursor} based on this snapshot. This is |
| 72 | done with a call to \Func{unw\_init\_local}(). The cursor now points |
| 73 | to the current frame, that is, the stack frame that corresponds to the |
| 74 | current activation of function \Func{F}(). The unwind cursor can then |
| 75 | be moved ``up'' (towards earlier stack frames) by calling |
| 76 | \Func{unw\_step}(). By repeatedly calling this routine, you can |
| 77 | uncover the entire call-chain that led to the activation of function |
| 78 | \Func{F}(). A positive return value from \Func{unw\_step}() indicates |
| 79 | that there are more frames in the chain, zero indicates that the end |
| 80 | of the chain has been reached, and any negative value indicates that |
| 81 | some sort of error has occurred. |
| 82 | |
| 83 | While it is not possible to directly move the unwind cursor in the |
| 84 | ``down'' direction (towards newer stack frames), this effect can be |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 85 | achieved by making copies of an unwind cursor. For example, a program |
| 86 | that sometimes has to move ``down'' by one stack frame could maintain |
| 87 | two cursor variables: ``\Var{curr}'' and ``\Var{prev}''. The former |
| 88 | would be used as the current cursor and \Var{prev} would be maintained |
| 89 | as the ``previous frame'' cursor by copying the contents of \Var{curr} |
| 90 | to \Var{prev} right before calling \Func{unw\_step}(). With this |
| 91 | approach, the program could move one step ``down'' simply by copying |
| 92 | back \Var{prev} to \Var{curr} whenever that is necessary. In the most |
| 93 | extreme case, a program could maintain a separate cursor for each call |
| 94 | frame and that way it could move up and down the callframe-chain at |
| 95 | will. |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 96 | |
| 97 | Given an unwind cursor, it is possible to read and write the CPU |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 98 | registers that were preserved for the current stack frame (as |
| 99 | identified by the cursor). \Prog{Libunwind} provides several routines |
| 100 | for this purpose: \Func{unw\_get\_reg}() reads an integer (general) |
| 101 | register, \Func{unw\_get\_fpreg}() reads a floating-point register, |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 102 | \Func{unw\_set\_reg}() writes an integer register, and |
| 103 | \Func{unw\_set\_fpreg}() writes a floating-point register. Note that, |
| 104 | by definition, only the \emph{preserved} machine state can be accessed |
| 105 | during an unwind operation. Normally, this state consists of the |
| 106 | \emph{callee-saved} (``preserved'') registers. However, in some |
| 107 | special circumstances (e.g., in a signal handler trampoline), even the |
| 108 | \emph{caller-saved} (``scratch'') registers are preserved in the stack |
| 109 | frame and, in those cases, \Prog{libunwind} will grant access to them |
| 110 | as well. The exact set of registers that can be accessed via the |
| 111 | cursor depends, of course, on the platform. However, there are two |
| 112 | registers that can be read on all platforms: the instruction pointer |
| 113 | (IP), sometimes also known as the ``program counter'', and the stack |
| 114 | pointer (SP). In \Prog{libunwind}, these registers are identified by |
| 115 | the macros \Const{UNW\_REG\_IP} and \Const{UNW\_REG\_SP}, |
| 116 | respectively. |
| 117 | |
| 118 | Besides just moving the unwind cursor and reading/writing saved |
| 119 | registers, \Prog{libunwind} also provides the ability to resume |
| 120 | execution at an arbitrary stack frame. As you might guess, this is |
| 121 | useful for implementing non-local gotos and the exception handling |
| 122 | needed by some high-level languages such as Java. Resuming execution |
| 123 | with a particular stack frame simply requires calling |
| 124 | \Func{unw\_resume}() and passing the cursor identifying the target |
| 125 | frame as the only argument. |
| 126 | |
| 127 | Normally, \Prog{libunwind} supports both local and remote unwinding |
| 128 | (the latter will be explained in the next section). However, if you |
| 129 | tell libunwind that your program only needs local unwinding, then a |
| 130 | special implementation can be selected which may run much faster than |
| 131 | the generic implementation which supports both kinds of unwinding. To |
| 132 | select this optimized version, simply define the macro |
| 133 | \Const{UNW\_LOCAL\_ONLY} before including the headerfile |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 134 | \File{$<$libunwind.h$>$}. It is perfectly OK for a single program to |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 135 | employ both local-only and generic unwinding. That is, whether or not |
| 136 | \Const{UNW\_LOCAL\_ONLY} is defined is a choice that each source-file |
| 137 | (compilation-unit) can make on its own. Independent of the setting(s) |
| 138 | of \Const{UNW\_LOCAL\_ONLY}, you'll always link the same library into |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 139 | the program (normally \Opt{-l}\File{unwind}). Furthermore, the |
| 140 | portion of \Prog{libunwind} that manages unwind-info for dynamically |
| 141 | generated code is not affected by the setting of |
| 142 | \Const{UNW\_LOCAL\_ONLY}. |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 143 | |
| 144 | If we put all of the above together, here is how we could use |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 145 | \Prog{libunwind} to write a function ``\Func{show\_backtrace}()'' |
| 146 | which prints a classic stack trace: |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 147 | |
| 148 | \begin{verbatim} |
| 149 | #define UNW_LOCAL_ONLY |
| 150 | #include <libunwind.h> |
| 151 | |
| 152 | void show_backtrace (void) { |
| 153 | unw_cursor_t cursor; unw_context_t uc; |
| 154 | unw_word_t ip, sp; |
| 155 | |
| 156 | unw_getcontext(&uc); |
| 157 | unw_init_local(&cursor, &uc); |
| 158 | while (unw_step(&cursor) > 0) { |
| 159 | unw_get_reg(&cursor, UNW_REG_IP, &ip); |
| 160 | unw_get_reg(&cursor, UNW_REG_SP, &sp); |
(none)!davidm | bba579e | 2004-08-05 08:59:57 +0000 | [diff] [blame] | 161 | printf ("ip = %lx, sp = %lx\n", (long) ip, (long) sp); |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 162 | } |
| 163 | } |
| 164 | \end{verbatim} |
| 165 | |
| 166 | |
| 167 | \section{Remote Unwinding} |
| 168 | |
| 169 | \Prog{Libunwind} can also be used to unwind a stack in a ``remote'' |
| 170 | process. Here, ``remote'' may mean another process on the same |
| 171 | machine or even a process on a completely different machine from the |
| 172 | one that is running \Prog{libunwind}. Remote unwinding is typically |
| 173 | used by debuggers and instruction-set simulators, for example. |
| 174 | |
| 175 | Before you can unwind a remote process, you need to create a new |
| 176 | address-space object for that process. This is achieved with the |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 177 | \Func{unw\_create\_addr\_space}() routine. The routine takes two |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 178 | arguments: a pointer to a set of \emph{accessor} routines and an |
| 179 | integer that specifies the byte-order of the target process. The |
| 180 | accessor routines provide \Func{libunwind} with the means to |
| 181 | communicate with the remote process. In particular, there are |
| 182 | callbacks to read and write the process's memory, its registers, and |
| 183 | to access unwind information which may be needed by \Func{libunwind}. |
| 184 | |
| 185 | With the address space created, unwinding can be initiated by a call |
| 186 | to \Func{unw\_init\_remote}(). This routine is very similar to |
| 187 | \Func{unw\_init\_local}(), except that it takes an address-space |
| 188 | object and an opaque pointer as arguments. The routine uses these |
| 189 | arguments to fetch the initial machine state. \Prog{Libunwind} never |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 190 | uses the opaque pointer on its own, but instead just passes it on to |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 191 | the accessor (callback) routines. Typically, this pointer is used to |
| 192 | select, e.g., the thread within a process that is to be unwound. |
| 193 | |
| 194 | Once a cursor has been initialized with \Func{unw\_init\_remote}(), |
| 195 | unwinding works exactly like in the local case. That is, you can use |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 196 | \Func{unw\_step}() to move ``up'' in the call-chain, read and write |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 197 | registers, or resume execution at a particular stack frame by calling |
| 198 | \Func{unw\_resume}. |
| 199 | |
| 200 | |
| 201 | \section{Cross-platform and Multi-platform Unwinding} |
| 202 | |
| 203 | \Prog{Libunwind} has been designed to enable unwinding across |
| 204 | platforms (architectures). Indeed, a single program can use |
| 205 | \Prog{libunwind} to unwind an arbitrary number of target platforms, |
| 206 | all at the same time! |
| 207 | |
| 208 | We call the machine that is running \Prog{libunwind} the \emph{host} |
| 209 | and the machine that is running the process being unwound the |
| 210 | \emph{target}. If the host and the target platform are the same, we |
| 211 | call it \emph{native} unwinding. If they differ, we call it |
| 212 | \emph{cross-platform} unwinding. |
| 213 | |
| 214 | The principle behind supporting native, cross-platform, and |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 215 | multi-platform unwinding is very simple: for native unwinding, a |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 216 | program includes \File{$<$libunwind.h$>$} and uses the linker switch |
| 217 | \Opt{-l}\File{unwind}. For cross-platform unwinding, a program |
| 218 | includes \File{$<$libunwind-}\Var{PLAT}\File{.h$>$} and uses the linker |
| 219 | switch \Opt{-l}\File{unwind-}\Var{PLAT}, where \Var{PLAT} is the name |
| 220 | of the target platform (e.g., \File{ia64} for IA-64, \File{hppa-elf} |
| 221 | for ELF-based HP PA-RISC, or \File{x86} for 80386). Multi-platform |
| 222 | unwinding works exactly like cross-platform unwinding, the only |
| 223 | limitation is that a single source file (compilation unit) can include |
| 224 | at most one \Prog{libunwind} header file. In other words, the |
| 225 | platform-specific support for each supported target needs to be |
| 226 | isolated in separate source files---a limitation that shouldn't be an |
| 227 | issue in practice. |
| 228 | |
| 229 | Note that, by definition, local unwinding is possible only for the |
| 230 | native case. Attempting to call, e.g., \Func{unw\_local\_init}() when |
| 231 | targeting a cross-platform will result in a link-time error |
| 232 | (unresolved references). |
| 233 | |
| 234 | |
| 235 | \section{Thread- and Signal-Safety} |
| 236 | |
| 237 | |
| 238 | All \Prog{libunwind} routines are thread-safe. What this means is |
| 239 | that multiple threads may use \Prog{libunwind} simulatenously. |
| 240 | However, any given cursor may be accessed by only one thread at |
| 241 | any given time. |
| 242 | |
| 243 | To ensure thread-safety, some \Prog{libunwind} routines may have to |
| 244 | use locking. Such routines \emph{must~not} be called from signal |
| 245 | handlers (directly or indirectly) and are therefore \emph{not} |
| 246 | signal-safe. The manual page for each \Prog{libunwind} routine |
| 247 | identifies whether or not it is signal-safe, but as a general rule, |
| 248 | any routine that may be needed for \emph{local} unwinding is |
| 249 | signal-safe (e.g., \Func{unw\_step}() for local unwinding is |
| 250 | signal-safe). For remote-unwinding, \emph{none} of the |
| 251 | \Prog{libunwind} routines are guaranteed to be signal-safe. |
| 252 | |
| 253 | |
| 254 | \section{Unwinding Through Dynamically Generated Code} |
| 255 | |
| 256 | \Func{Libunwind} provides the routines \Func{\_U\_dyn\_register}() and |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 257 | \Func{\_U\_dyn\_cancel}() to register/cancel the information required to |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 258 | unwind through code that has been generated at runtime (e.g., by a |
| 259 | just-in-time (JIT) compiler). It is important to register the |
| 260 | information for \emph{all} dynamically generated code because |
| 261 | otherwise, a debugger may not be able to function properly or |
| 262 | high-level language exception handling may not work as expected. |
| 263 | |
| 264 | The interface for registering and canceling dynamic unwind info has |
| 265 | been designed for maximum efficiency, so as to minimize the |
| 266 | performance impact on JIT-compilers. In particular, both routines are |
| 267 | guaranteed to execute in ``constant time'' (O(1)) and the |
| 268 | data-structure encapsulating the dynamic unwind info has been designed |
| 269 | to facilitate sharing, such that similar procedures can share much of |
| 270 | the underlying information. |
| 271 | |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 272 | For more information on the \Prog{libunwind} support for dynamically |
| 273 | generated code, see \SeeAlso{libunwind-dynamic(3)}. |
| 274 | |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 275 | |
| 276 | \section{Caching of Unwind Info} |
| 277 | |
| 278 | To speed up execution, \Prog{libunwind} may aggressively cache the |
| 279 | information it needs to perform unwinding. If a process changes |
| 280 | during its lifetime, this creates a risk of \Prog{libunwind} using |
| 281 | stale data. For example, this would happen if \Prog{libunwind} were |
| 282 | to cache information about a shared library which later on gets |
| 283 | unloaded (e.g., via \Cmd{dlclose}{3}). |
| 284 | |
| 285 | To prevent the risk of using stale data, \Prog{libunwind} provides two |
| 286 | facilities: first, it is possible to flush the cached information |
| 287 | associated with a specific address range in the target process (or the |
| 288 | entire address space, if desired). This functionality is provided by |
| 289 | \Func{unw\_flush\_cache}(). The second facility is provided by |
| 290 | \Func{unw\_set\_caching\_policy}(), which lets a program |
| 291 | select the exact caching policy in use for a given address-space |
| 292 | object. In particular, by selecting the policy |
| 293 | \Const{UNW\_CACHE\_NONE}, it is possible to turn off caching |
| 294 | completely, therefore eliminating the risk of stale data alltogether |
| 295 | (at the cost of slower execution). By default, caching is enabled for |
| 296 | local unwinding only. |
| 297 | |
| 298 | |
| 299 | \section{Files} |
| 300 | |
| 301 | \begin{Description} |
| 302 | \item[\File{libunwind.h}] Headerfile to include for native (same |
| 303 | platform) unwinding. |
| 304 | \item[\File{libunwind-}\Var{PLAT}\File{.h}] Headerfile to include when |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 305 | the unwind target runs on platform \Var{PLAT}. For example, to unwind |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 306 | an IA-64 program, the header file \File{libunwind-ia64.h} should be |
| 307 | included. |
| 308 | \item[\Opt{-l}\File{unwind}] Linker-switch to add when building a |
| 309 | program that does native (same platform) unwinding. |
| 310 | \item[\Opt{-l}\File{unwind-}\Var{PLAT}] Linker-switch to add when |
| 311 | building a program that unwinds a program on platform \Var{PLAT}. |
| 312 | For example, to (cross-)unwind an IA-64 program, the linker switch |
| 313 | \File{-lunwind-ia64} should be added. Note: multiple such switches |
mostang.com!davidm | 2a5ff2d | 2003-03-27 04:29:07 +0000 | [diff] [blame] | 314 | may need to be specified for programs that can unwind programs on |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 315 | multiple platforms. |
| 316 | \end{Description} |
| 317 | |
| 318 | \section{See Also} |
| 319 | |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 320 | \SeeAlso{libunwind-dynamic(3)}, |
mostang.com!davidm | f5892c2 | 2003-02-08 10:10:59 +0000 | [diff] [blame] | 321 | \SeeAlso{libunwind-ia64(3)}, |
| 322 | \SeeAlso{libunwind-ptrace(3)}, |
| 323 | \SeeAlso{libunwind-setjmp(3)}, |
mostang.com!davidm | a21507d | 2003-03-20 07:51:37 +0000 | [diff] [blame] | 324 | \SeeAlso{unw\_create\_addr\_space(3)}, |
| 325 | \SeeAlso{unw\_destroy\_addr\_space(3)}, |
| 326 | \SeeAlso{unw\_flush\_cache(3)}, |
| 327 | \SeeAlso{unw\_get\_accessors(3)}, |
| 328 | \SeeAlso{unw\_get\_fpreg(3)}, |
| 329 | \SeeAlso{unw\_get\_proc\_info(3)}, |
| 330 | \SeeAlso{unw\_get\_proc\_name(3)}, |
| 331 | \SeeAlso{unw\_get\_reg(3)}, |
| 332 | \SeeAlso{unw\_getcontext(3)}, |
| 333 | \SeeAlso{unw\_init\_local(3)}, |
| 334 | \SeeAlso{unw\_init\_remote(3)}, |
| 335 | \SeeAlso{unw\_is\_fpreg(3)}, |
| 336 | \SeeAlso{unw\_is\_signal\_frame(3)}, |
| 337 | \SeeAlso{unw\_regname(3)}, |
| 338 | \SeeAlso{unw\_resume(3)}, |
| 339 | \SeeAlso{unw\_set\_caching\_policy(3)}, |
| 340 | \SeeAlso{unw\_set\_fpreg(3)}, |
| 341 | \SeeAlso{unw\_set\_reg(3)}, |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 342 | \SeeAlso{unw\_step(3)}, |
David Mosberger-Tang | 75f34cc | 2007-08-22 12:49:08 -0600 | [diff] [blame] | 343 | \SeeAlso{unw\_strerror(3)}, |
mostang.com!davidm | 4ea1dd7 | 2003-12-10 07:14:38 +0000 | [diff] [blame] | 344 | \SeeAlso{\_U\_dyn\_register(3)}, |
| 345 | \SeeAlso{\_U\_dyn\_cancel(3)} |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 346 | |
| 347 | \section{Author} |
| 348 | |
| 349 | \noindent |
| 350 | David Mosberger-Tang\\ |
David Mosberger-Tang | 75f34cc | 2007-08-22 12:49:08 -0600 | [diff] [blame] | 351 | Email: \Email{dmosberger@gmail.com}\\ |
| 352 | WWW: \URL{http://www.nongnu.org/libunwind/}. |
mostang.com!davidm | b5a5406 | 2003-01-17 07:48:52 +0000 | [diff] [blame] | 353 | \LatexManEnd |
| 354 | |
| 355 | \end{document} |