1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-14 12:18:12 +01:00

unw_init_local_signal

init_local, but *not* setting use_prev_instr.
This is necessary to correctly unwind using ucontext argument to signal handlers.
This commit is contained in:
Doug Moore 2017-03-30 14:35:35 -07:00 committed by Dave Watson
parent 2b8ab794b3
commit 14c48b3d51
15 changed files with 171 additions and 55 deletions

View file

@ -11,6 +11,7 @@ man3_MANS = libunwind.man libunwind-dynamic.man libunwind-ia64.man \
unw_get_reg.man \ unw_get_reg.man \
unw_getcontext.man \ unw_getcontext.man \
unw_init_local.man unw_init_remote.man \ unw_init_local.man unw_init_remote.man \
unw_init_local_signal.man \
unw_is_fpreg.man \ unw_is_fpreg.man \
unw_is_signal_frame.man \ unw_is_signal_frame.man \
unw_create_addr_space.man \ unw_create_addr_space.man \

View file

@ -1,5 +1,5 @@
'\" t '\" t
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 .\" Manual page created with latex2man on Thu Mar 30 16:13:10 PDT 2017
.\" NOTE: This file is generated, DO NOT EDIT. .\" NOTE: This file is generated, DO NOT EDIT.
.de Vb .de Vb
.ft CW .ft CW
@ -10,7 +10,7 @@
.fi .fi
.. ..
.TH "UNW\\_INIT\\_LOCAL" "3" "16 August 2007" "Programming Library " "Programming Library " .TH "UNW\\_INIT\\_LOCAL" "3" "30 March 2017" "Programming Library " "Programming Library "
.SH NAME .SH NAME
unw_init_local unw_init_local
\-\- initialize cursor for local unwinding \-\- initialize cursor for local unwinding
@ -25,6 +25,10 @@ int
unw_init_local(unw_cursor_t *c, unw_init_local(unw_cursor_t *c,
unw_context_t *ctxt); unw_context_t *ctxt);
.br .br
int
unw_init_local_signal(unw_cursor_t *c,
unw_context_t *ctxt);
.br
.PP .PP
.SH DESCRIPTION .SH DESCRIPTION
@ -37,7 +41,11 @@ pointed to by ctxt\&.
As such, the machine\-state pointed to by As such, the machine\-state pointed to by
ctxt ctxt
identifies the initial stack frame at which unwinding identifies the initial stack frame at which unwinding
starts. The machine\-state must remain valid for the duration for starts. The machine\-state is expected to be one provided by a call to
unw_getcontext; as such, the instruction pointer may point to the
instruction after the last instruction of a function, and libunwind
will back\-up the instruction pointer before beginning a walk up the
call stack. The machine\-state must remain valid for the duration for
which the cursor c which the cursor c
is in use. is in use.
.PP .PP
@ -46,17 +54,6 @@ routine can be used only for unwinding in
the address space of the current process (i.e., for local unwinding). the address space of the current process (i.e., for local unwinding).
For all other cases, unw_init_remote() For all other cases, unw_init_remote()
must be used instead. must be used instead.
From a behavioral point of view, the call:
.PP
.Vb
ret = unw_init_local(&cursor, &ucontext);
.Ve
is equivalent to:
.PP
.Vb
ret = unw_init_remote(&cursor, unw_local_addr_space,
&ucontext);
.Ve
However, unwind performance may be better when using However, unwind performance may be better when using
unw_init_local(). unw_init_local().
Also, unw_init_local() Also, unw_init_local()
@ -67,6 +64,12 @@ including <libunwind.h>,
whereas unw_init_remote() whereas unw_init_remote()
is not. is not.
.PP .PP
If the unw_context_t is known to be a signal frame (i.e., from the
third argument in a sigaction handler on linux),
unw_init_local_signal()
should be used for correct
initialization on some platforms.
.PP
.SH RETURN VALUE .SH RETURN VALUE
.PP .PP

View file

@ -13,6 +13,7 @@
\File{\#include $<$libunwind.h$>$}\\ \File{\#include $<$libunwind.h$>$}\\
\Type{int} \Func{unw\_init\_local}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_context\_t~*}\Var{ctxt});\\ \Type{int} \Func{unw\_init\_local}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_context\_t~*}\Var{ctxt});\\
\Type{int} \Func{unw\_init\_local_signal}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_context\_t~*}\Var{ctxt});\\
\section{Description} \section{Description}
@ -20,29 +21,27 @@ The \Func{unw\_init\_local}() routine initializes the unwind cursor
pointed to by \Var{c} with the machine-state in the context structure pointed to by \Var{c} with the machine-state in the context structure
pointed to by \Var{ctxt}. As such, the machine-state pointed to by pointed to by \Var{ctxt}. As such, the machine-state pointed to by
\Var{ctxt} identifies the initial stack frame at which unwinding \Var{ctxt} identifies the initial stack frame at which unwinding
starts. The machine-state must remain valid for the duration for starts. The machine-state is expected to be one provided by a call to
unw_getcontext; as such, the instruction pointer may point to the
instruction after the last instruction of a function, and libunwind
will back-up the instruction pointer before beginning a walk up the
call stack. The machine-state must remain valid for the duration for
which the cursor \Var{c} is in use. which the cursor \Var{c} is in use.
The \Func{unw\_init\_local}() routine can be used only for unwinding in The \Func{unw\_init\_local}() routine can be used only for unwinding in
the address space of the current process (i.e., for local unwinding). the address space of the current process (i.e., for local unwinding).
For all other cases, \Func{unw\_init\_remote}() must be used instead. For all other cases, \Func{unw\_init\_remote}() must be used instead.
From a behavioral point of view, the call:
\begin{verbatim}
ret = unw_init_local(&cursor, &ucontext);
\end{verbatim}
is equivalent to:
\begin{verbatim}
ret = unw_init_remote(&cursor, unw_local_addr_space,
&ucontext);
\end{verbatim}
However, unwind performance may be better when using However, unwind performance may be better when using
\Func{unw\_init\_local}(). Also, \Func{unw\_init\_local}() is \Func{unw\_init\_local}(). Also, \Func{unw\_init\_local}() is
available even when \Const{UNW\_LOCAL\_ONLY} has been defined before available even when \Const{UNW\_LOCAL\_ONLY} has been defined before
including \File{$<$libunwind.h$>$}, whereas \Func{unw\_init\_remote}() including \File{$<$libunwind.h$>$}, whereas \Func{unw\_init\_remote}()
is not. is not.
If the unw_context_t is known to be a signal frame (i.e., from the
third argument in a sigaction handler on linux),
\Func{unw\_init\_local\_signal}() should be used for correct
initialization on some platforms.
\section{Return Value} \section{Return Value}
On successful completion, \Func{unw\_init\_local}() returns 0. On successful completion, \Func{unw\_init\_local}() returns 0.

View file

@ -0,0 +1 @@
.so man3/unw_init_local.3

View file

@ -211,6 +211,7 @@ unw_save_loc_t;
#define unw_destroy_addr_space UNW_OBJ(destroy_addr_space) #define unw_destroy_addr_space UNW_OBJ(destroy_addr_space)
#define unw_get_accessors UNW_ARCH_OBJ(get_accessors) #define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
#define unw_init_local UNW_OBJ(init_local) #define unw_init_local UNW_OBJ(init_local)
#define unw_init_local_signal UNW_OBJ(init_local_signal)
#define unw_init_remote UNW_OBJ(init_remote) #define unw_init_remote UNW_OBJ(init_remote)
#define unw_step UNW_OBJ(step) #define unw_step UNW_OBJ(step)
#define unw_resume UNW_OBJ(resume) #define unw_resume UNW_OBJ(resume)
@ -239,6 +240,7 @@ extern int unw_set_cache_size (unw_addr_space_t, size_t, int);
extern const char *unw_regname (unw_regnum_t); extern const char *unw_regname (unw_regnum_t);
extern int unw_init_local (unw_cursor_t *, unw_context_t *); extern int unw_init_local (unw_cursor_t *, unw_context_t *);
extern int unw_init_local_signal (unw_cursor_t *, unw_context_t *);
extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *); extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *);
extern int unw_step (unw_cursor_t *); extern int unw_step (unw_cursor_t *);
extern int unw_resume (unw_cursor_t *); extern int unw_resume (unw_cursor_t *);

View file

@ -36,8 +36,8 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -49,7 +49,19 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, unw_context_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -36,8 +36,8 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -49,7 +49,19 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, unw_context_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -36,8 +36,8 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -48,7 +48,19 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -35,8 +35,8 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -47,7 +47,19 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local(unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal(unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -43,8 +43,8 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -56,10 +56,22 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
#ifdef UNW_TARGET_PPC64 #ifdef UNW_TARGET_PPC64
return common_init_ppc64 (c, 1); return common_init_ppc64 (c, use_prev_instr);
#else #else
return common_init_ppc32 (c, 1); return common_init_ppc32 (c, use_prev_instr);
#endif #endif
} }
PROTECTED int
unw_init_local(unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal(unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
}
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -36,8 +36,8 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) unw_init_local (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -49,7 +49,19 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, unw_context_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -36,8 +36,8 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -51,7 +51,19 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->dwarf.as = unw_local_addr_space; c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc; c->dwarf.as_arg = uc;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -36,8 +36,8 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -50,7 +50,19 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->dwarf.as_arg = c; c->dwarf.as_arg = c;
c->uc = uc; c->uc = uc;
c->validate = 0; c->validate = 0;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -38,8 +38,8 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
#else /* !UNW_REMOTE_ONLY */ #else /* !UNW_REMOTE_ONLY */
PROTECTED int static int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
@ -52,7 +52,19 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->dwarf.as_arg = c; c->dwarf.as_arg = c;
c->uc = uc; c->uc = uc;
c->validate = 0; c->validate = 0;
return common_init (c, 1); return common_init (c, use_prev_instr);
}
PROTECTED int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 1);
}
PROTECTED int
unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc)
{
return unw_init_local_common(cursor, uc, 0);
} }
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */

View file

@ -97,6 +97,7 @@ check_local_unw_abi () {
match _UL${plat}_get_reg match _UL${plat}_get_reg
match _UL${plat}_get_save_loc match _UL${plat}_get_save_loc
match _UL${plat}_init_local match _UL${plat}_init_local
match _UL${plat}_init_local_signal
match _UL${plat}_init_remote match _UL${plat}_init_remote
match _UL${plat}_is_signal_frame match _UL${plat}_is_signal_frame
match _UL${plat}_handle_signal_frame match _UL${plat}_handle_signal_frame
@ -172,7 +173,7 @@ check_local_unw_abi () {
match _UL${plat}_local_addr_space_init match _UL${plat}_local_addr_space_init
match _U${plat}_get_elf_image match _U${plat}_get_elf_image
match _U${plat}_get_exe_image_path match _U${plat}_get_exe_image_path
match ${plat}_lock match ${plat}_lock
;; ;;
*) *)
@ -200,6 +201,7 @@ check_generic_unw_abi () {
match _U${plat}_get_reg match _U${plat}_get_reg
match _U${plat}_get_save_loc match _U${plat}_get_save_loc
match _U${plat}_init_local match _U${plat}_init_local
match _U${plat}_init_local_signal
match _U${plat}_init_remote match _U${plat}_init_remote
match _U${plat}_is_signal_frame match _U${plat}_is_signal_frame
match _U${plat}_handle_signal_frame match _U${plat}_handle_signal_frame