Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
LIBUNWIND(3libunwind)	      Programming Library	   LIBUNWIND(3libunwind)

NAME
     libunwind -- a (mostly) platform-independent unwind API

SYNOPSIS
     #include <libunwind.h>

     int unw_getcontext(unw_context_t *);
     int unw_init_local(unw_cursor_t *, unw_context_t *);
     int unw_init_remote(unw_cursor_t *, unw_addr_space_t, void *);
     int unw_step(unw_cursor_t *);
     int unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *);
     int unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *);
     int unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t);
     int unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t);
     int unw_resume(unw_cursor_t *);

     unw_addr_space_t unw_local_addr_space;
     unw_addr_space_t unw_create_addr_space(unw_accessors_t, int);
     void unw_destroy_addr_space(unw_addr_space_t);
     unw_accessors_t unw_get_accessors(unw_addr_space_t);
     void unw_flush_cache(unw_addr_space_t, unw_word_t, unw_word_t);
     int unw_set_caching_policy(unw_addr_space_t, unw_caching_policy_t);
     int unw_set_cache_size(unw_addr_space_t, size_t, int);

     const char *unw_regname(unw_regnum_t);
     int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *);
     int unw_get_save_loc(unw_cursor_t *, int, unw_save_loc_t *);
     int unw_is_fpreg(unw_regnum_t);
     int unw_is_signal_frame(unw_cursor_t *);
     int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *);

     void _U_dyn_register(unw_dyn_info_t *);
     void _U_dyn_cancel(unw_dyn_info_t *);

LOCAL UNWINDING
     Libunwind	is very easy to use when unwinding a stack from within a running
     program. This is called local 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 unwind cursor 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  ear-
     lier  stack frames) by calling unw_step().  By repeatedly calling this rou-
     tine, 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.

     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 mak-
     ing  copies  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 ap-
     proach, the program could move one step ``down''  simply  by  copying  back
     prev  to  curr whenever that is necessary. In the most extreme case, a pro-
     gram could maintain a separate cursor for each call frame and that  way  it
     could move up and down the callframe 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 (as identified by the  cur-
     sor).  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 pre-
     served machine state can be accessed during an unwind operation.  Normally,
     this state consists of the callee-saved (``preserved'') registers. However,
     in  some special circumstances (e.g., in a signal handler trampoline), even
     the caller-saved (``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 ``pro-
     gram counter'', and the stack pointer (SP). In libunwind,	these  registers
     are identified by the macros UNW_REG_IP and UNW_REG_SP, respectively.

     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.

     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 <libun-
     wind.h>.  It 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.  In-
     dependent	of the setting(s) of UNW_LOCAL_ONLY, you'll always link the same
     library into the program (normally -lunwind).  Furthermore, the portion  of
     libunwind	that  manages  unwind info for dynamically generated code is not
     affected by the setting of UNW_LOCAL_ONLY.

     If we put all of the above together, here is how we could use libunwind  to
     write a function ``show_backtrace()'' which prints a classic stack trace:

     #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 = %lx, sp = %lx\n", (long) ip, (long) sp);
       }
     }

REMOTE UNWINDING
     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 simula-
     tors, 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	unw_cre-
     ate_addr_space()  routine.  The routine takes two arguments: a pointer to a
     set of accessor 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.

     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(),  ex-
     cept  that  it takes an address space object and an opaque pointer as argu-
     ments. The routine uses these arguments to fetch the initial machine state.
     Libunwind never uses the opaque pointer on its own, but instead just 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 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.

CROSS-PLATFORM AND MULTI-PLATFORM UNWINDING
     Libunwind has been designed to enable unwinding across platforms (architec-
     tures). Indeed, a single program can use libunwind to unwind  an  arbitrary
     number of target platforms, all at the same time!

     We call the machine that is running libunwind the host and the machine that
     is  running the process being unwound the target.	If the host and the tar-
     get platform are the same, we call it native unwinding. If they differ,  we
     call it cross-platform unwinding.

     The  principle behind supporting native, cross-platform, and multi-platform
     unwinding is very simple: for native unwinding, a program includes  <libun-
     wind.h> and uses the linker switch -lunwind.  For cross-platform unwinding,
     a	program  includes  <libunwind-PLAT.h>  and  uses the linker switch -lun-
     wind-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 li-
     bunwind header file. In other words, the platform-specific support for each
     supported target needs to be isolated in separate source files---a  limita-
     tion 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.,  unw_local_init()  when   targeting   a
     cross-platform will result in a link-time error (unresolved references).

THREAD- AND SIGNAL-SAFETY
     All  libunwind  routines  are thread-safe. What this means is that multiple
     threads may use libunwind simultaneously.	However, any given cursor may be
     accessed by only one thread at any given time.

     To ensure thread safety, some libunwind routines may have to  use	locking.
     Such  routines  must  not be called from signal handlers (directly or indi-
     rectly) and are therefore not signal-safe. The manual page for each  libun-
     wind  routine identifies whether or not it is signal-safe, but as a general
     rule, any routine that may be needed for  local  unwinding  is  signal-safe
     (e.g.,  unw_step()  for local unwinding is signal-safe). For remote unwind-
     ing, none of the libunwind routines are guaranteed to be signal-safe.

UNWINDING THROUGH DYNAMICALLY GENERATED CODE
     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 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 pro-
     cedures can share much of the underlying information.

     For more information on the libunwind  support  for  dynamically  generated
     code, see libunwind-dynamic(3libunwind).

CACHING OF UNWIND INFO
     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 hap-
     pen if libunwind were to cache information about  a  shared  library  which
     later on gets unloaded (e.g., via dlclose(3libunwind)).

     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 sec-
     ond  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 alto-
     gether (at the cost of slower execution). By default,  caching  is  enabled
     for  local  unwinding  only. The cache size can be dynamically changed with
     unw_set_cache_size(), which also flushes the current cache.

FILES
     libunwind.h
	     Headerfile to include for native (same platform) unwinding.

     libunwind-PLAT.h
	     Headerfile to include when the unwind target runs on platform PLAT.
	    For example, to unwind an IA-64  program,  the  header  file  libun-
	    wind-ia64.h should be included.

     -lunwind
	     Linker switch to add when building a program that does native (same
	    platform) unwinding.

     -lunwind-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  pro-
	    grams on multiple platforms.

SEE ALSO
     libunwind-dynamic(3libunwind),	 libunwind-ia64(3libunwind),	  libun-
     wind-ptrace(3libunwind),	    libunwind-setjmp(3libunwind),	unw_cre-
     ate_addr_space(3libunwind),	     unw_destroy_addr_space(3libunwind),
     unw_flush_cache(3libunwind),		  unw_get_accessors(3libunwind),
     unw_get_fpreg(3libunwind), 		  unw_get_proc_info(3libunwind),
     unw_get_proc_name(3libunwind), unw_get_reg(3libunwind), unw_getcontext(3li-
     bunwind),	   unw_init_local(3libunwind),	    unw_init_remote(3libunwind),
     unw_is_fpreg(3libunwind), unw_is_signal_frame(3libunwind), unw_regname(3li-
     bunwind),	  unw_resume(3libunwind),    unw_set_caching_policy(3libunwind),
     unw_set_cache_size(3libunwind), unw_set_fpreg(3libunwind), unw_set_reg(3li-
     bunwind),	unw_step(3libunwind),  unw_strerror(3libunwind),   _U_dyn_regis-
     ter(3libunwind), _U_dyn_cancel(3libunwind)

AUTHOR
     David Mosberger-Tang
     Email: dmosberger@gmail.com
     WWW: http://www.nongnu.org/libunwind/.

Programming Library		 29 August 2023 	   LIBUNWIND(3libunwind)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libunwind&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help