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 run-
       ning  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 (ma-
       chine  state). Then you initialize an unwind cursor based on this snap-
       shot. 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.

       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 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  approach, the	program	could move one
       step ``down'' simply by copying back prev to curr whenever that is nec-
       essary. In the most extreme case, a program 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	regis-
       ters that were preserved	for the	current	stack frame (as	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	regis-
       ter,  and  unw_set_fpreg() writes a floating-point register. Note that,
       by definition, only the preserved 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
       ``program  counter'',  and  the stack pointer (SP). In libunwind, these
       registers are identified	by the macros UNW_REG_IP and  UNW_REG_SP,  re-
       spectively.

       Besides	just moving the	unwind cursor and reading/writing saved	regis-
       ters, libunwind also provides the ability to resume execution at	an ar-
       bitrary stack frame. As you might guess,	this is	useful for  implement-
       ing   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  lat-
       ter will	be explained in	the next section). However, if you tell	libun-
       wind  that  your	program	only needs local unwinding, then a special im-
       plementation 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 in-
       cluding the headerfile <libunwind.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. Independent of the set-
       ting(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  in-
       struction-set simulators, for example.

       Before  you  can	 unwind	a remote process, you need to create a new ad-
       dress 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(),
       except that it takes an address space object and	an opaque  pointer  as
       arguments.  The	routine	 uses these arguments to fetch the initial ma-
       chine state. Libunwind never uses the opaque pointer on	its  own,  but
       instead	just  passes  it on to the accessor (callback) routines. Typi-
       cally, 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  (ar-
       chitectures).  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 target 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-plat-
       form unwinding is very simple: for native unwinding, a program includes
       <libunwind.h>  and uses the linker switch -lunwind.  For	cross-platform
       unwinding, a program includes <libunwind-PLAT.h>	and  uses  the	linker
       switch  -lunwind-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 un-
       winding,	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.

       Note that, by definition, local unwinding is possible only for the  na-
       tive  case. Attempting to call, e.g., unw_local_init() when targeting a
       cross-platform will result in  a	 link-time  error  (unresolved	refer-
       ences).

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

       To  ensure thread safety, some libunwind	routines may have to use lock-
       ing. Such routines must not be called from signal handlers (directly or
       indirectly) and are therefore not 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  local	 unwinding  is
       signal-safe  (e.g., unw_step() for local	unwinding is signal-safe). For
       remote unwinding, 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	gener-
       ated  code  because  otherwise,	a debugger may not be able to function
       properly	or high-level language exception handling may not work as  ex-
       pected.

       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  encapsulat-
       ing  the	 dynamic  unwind info has been designed	to facilitate sharing,
       such that similar procedures can	share much of the underlying  informa-
       tion.

       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 life-
       time, 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 dlclose(3libunwind)).

       To prevent the risk of using stale data,	libunwind provides two facili-
       ties:  first, it	is possible to flush the cached	information associated
       with a specific address range in	the target process (or the entire  ad-
       dress   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 se-
       lecting the policy UNW_CACHE_NONE, it is	possible to turn  off  caching
       completely, therefore eliminating the risk of stale data	altogether (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
	      libunwind-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  pro-
	      grams that can unwind programs 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_getcon-
       text(3libunwind),  unw_init_local(3libunwind),  unw_init_remote(3libun-
       wind),	 unw_is_fpreg(3libunwind),    unw_is_signal_frame(3libunwind),
       unw_regname(3libunwind),	 unw_resume(3libunwind),  unw_set_caching_pol-
       icy(3libunwind),	unw_set_cache_size(3libunwind),	 unw_set_fpreg(3libun-
       wind), unw_set_reg(3libunwind), unw_step(3libunwind), unw_strerror(3li-
       bunwind), _U_dyn_register(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+14.3.quarterly>

home | help