|
» |
|
|
|
NAME_UNW_createContextForSelf(), _UNW_createContext(), _UNW_destroyContext() — allocate and deallocate unwind library data structure SYNOPSIS#include <unwind.h>
_Unwind_Context * _UNW_createContextForSelf(void);
_Unwind_Context * _UNW_createContext(
_UNW_ReadTargetMem read_tgt_mem,
_UNW_LoadMapFromIP load_map_from_ip,
uint32_t ident);
void _UNW_destroyContext(_Unwind_Context* p); DESCRIPTION_UNW_createContextForSelf
and
_UNW_createContext
each initialize a data structure called
_Unwind_Context,
which is managed by the stack unwind library, supplied as
libunwind.so.
_UNW_createContextForSelf
is typically used when a process intends to unwind its own stack.
_UNW_createContext
is typically used when a process intends to unwind a different process'
stack or the
stack of a "dead" process preserved in a core file. When using
_UNW_createContext
for unwinding a process (referred to as the target process),
the client process is required to provide three parameters:
- 1.
Parameter
read_tgt_mem
is a function which
the unwind library
calls to read values from the target process memory
including the unwind header, unwind table and unwind information blocks,
the procedure call stack, and the Register Stack Engine backing store.
It must be able to read from anywhere in the 64-bit address space (even for
32-bit applications) since the
Integrity
systems' kernel interruption
unwind header is read from kernel gateway memory pages. read_tgt_mem
has type definition
_UNW_ReadTargetMem,
which is defined in
unwind.h
as
typedef void * (* _UNW_ReadTargetMem) (void *dst,
uint64_t src,
size_t length,
uint32_t ident); The parameters are almost synonymous with those for
memcpy(3C).
Parameter
dst
is the destination address to which parameter
length
bytes are copied from parameter
src.
Note that
src
is of type
uint64_t
in order to represent the 64-bit addresses required for reading the kernel
gateway page.
When unwinding through a 64-bit application, all
src
and
dst
addresses used during unwinding are 64-bit pointers.
When unwinding through a 32-bit application's code, most addresses used during
unwinding are 32-bit pointers (although the unwind library
swizzles
them
to fully qualified 64-bit addresses before calling the target memory reader).
The memory model and the term
"swizzle"
are explained in detail in
Itanium Processor Family Runtime Architecture Supplement:
32-Bit Runtime Architecture for HP-UX,
"Section 1: Memory Model". The only range of addresses which require 64-bit
pointers (and therefore unreachable from the 32-bit address space) are those associated
with the unwind header and unwind information
for the kernel's signal handler wrapper function
__user_sendsig.
The client's memory read callback function must be able to detect this range
and to read this range of addresses.
The range is
defined at program startup time by the microloader and dynamic loader (or in
crt0.o
for fully bound executables) in a structure
load_info_t,
defined in
/usr/include/crt0.h.
See
Itanium Processor Family Runtime Architecture Supplement: Signal Handling on HP-UX
and
Itanium Processor Family Runtime Architecture Supplement: Program Startup on HP-UX. read_tgt_mem's
third parameter,
ident,
is transparent to the unwind library itself, and is provided for the use of
the unwinder client program.
The client program supplies the unwind library
with a value for
ident
(via the call to
_UNW_createContext)
which the unwind library in turn passes along to the
read_tgt_mem
callback.
A debugger, for example, can use
ident
to identify separate threads within the target process. - 2.
Parameter
load_map_from_ip
is a function which
the unwind library
calls in place of calls to
dlmodinfo
when it needs to obtain a
load_module_desc
for a given IP address in target process memory
(See
dlmodinfo(3C)).
When called,
load_map_from_ip
must fill in a
load_module_desc
structure with accurate values for fields
linkage_ptr,
unwind_base,
and
text_base
for any valid user process instruction address including instruction
addresses associated with
__user_sendsig.
Unwind_base
(which is the location of the
unwind header),
and
text_base,
(which is the location at which the ELF
.text
segment is loaded),
must each be full 64-bit addresses (as opposed to 32-bit
un-swizzled
pointers).
Linkage_ptr
is the (full 64-bit) value of a procedure's
GP
register.
See
Itanium Processor Family Software Conventions and Runtime Architecture:
Chapter 8,
Procedure Linkage.
The unwind information for
__user_sendsig
is communicated in the kernel gateway page as described
in the discussion of
read_tgt_mem
above. load_map_from_ip
has type definition
_UNW_LoadMapFromIP
which is defined in
unwind.h
as
typedef void (* _UNW_LoadMapFromIP) (
struct load_module_desc * new_load_map,
uint64_t ip,
uint32_t ident); Parameter
new_load_map
is a pointer to a pre-allocated
struct load_module_desc
to be filled in by
load_map_from_ip. Parameter
ip
is any instruction pointer associated with the load module for which
information is requested. Parameter
ident
is transparent to the unwind library itself, and is provided for the use of
the unwinder client program.
The client program supplies the unwind library with a value for
ident
(via the call to
_UNW_createContext)
which the unwind library, in turn, passes along to the
load_map_from_ip
callback.
A debugger, for example, can use
ident
to identify separate threads within the target process. - 3.
The semantics of
_UNW_createContext's
third parameter
ident,
which is provided for the use of the
unwinder client program, is discussed in the
read_tgt_mem
and
load_map_from_ip
paragraphs above.
Although
_UNW_createContext
was designed to fulfill the requirement of unwinding a process other
than self, the
_Unwind_Context
created
_UNW_createContext
can be used by a process to unwind itself as well.
Reasons for doing so include the unwinding of dynamically generated
code or run-time instrumented code.
In these situations, the client may
need to register
_UNW_LoadMapFromIP
and
_UNW_ReadTargetMem
callbacks. _UNW_destroyContext
frees memory allocated by
_UNW_createContextForSelf
or by
_UNW_createContext.
To avoid memory leaks, an application that allocates an
_Unwind_Context
object should call
_UNW_destroyContext
when the
_Unwind_Context
is no longer needed. APPLICATION USAGE_UNW_createContextForSelf,
_UNW_createContext,
and
_UNW_destroyContext
are thread-safe. RETURN VALUEPointer to struct
_Unwind_Context. ERRORS_UNW_createContextForSelf
and
_UNW_createContext
can fail to create the unwind context data structure
under the following conditions:
Low memory conditions.
The following Unwind library behavior is guaranteed
in low memory conditions: A failed construction of a
_Unwind_Context
creates for the client program enough of an
_Unwind_Context
object to support a call to the
the stack unwind library entry point
_UNW_getAlertCode() ,
which returns
_UNW_MEMORY_ALLOCATION_ERROR
in the event of a failed construction or if the
_Unwind_Context
pointer is NULL (also an indicator of failed construction).
Had the construction been successful,
_UNW_getAlertCode()
would have returned
_UNW_OK. Failed construction in extremely low memory conditions
is communicated by returning
NULL
in effect setting the
_Unwind_Context
pointer to
NULL.
Subsequent calls to interface functions of return type
_UNW_ReturnCode
return
_UNW_MEMORY_ALLOCATION_ERROR
if the
_Unwind_Context
pointer is
NULL.
EXAMPLESExample 1Allocate and initialize an
_Unwind_Context
for unwinding the currently
running process:
#include <unwind.h>
#include <stdio.h>
_Unwind_Context *uc;
_UNW_ReturnCode retcode;
uc = _UNW_createContextForSelf();
if (uc == NULL) {
/* Code to notify user of low memory problem */
}
if (_UNW_getAlertCode(uc) == _UNW_MEMORY_ALLOCATION_ERROR) {
/* Code to notify user of low memory problem */
}
/* Example use of the _Unwind_Context * follows: */
if ((retcode = _UNW_currentContext(uc)) != _UNW_OK) {
/* Notify user: Couldn't determine current context. */
} Example 2Allocate and initialize an
_Unwind_Context
for unwinding a process
other than the running process:
#include <unwind.h>
#include <stdio.h>
_Unwind_Context *uc;
_UNW_ReturnCode retcode;
extern _UNW_ReadTargetMem my_mem_reader;
extern _UNW_LoadMapFromIP my_dlmodule_info;
uint64_t target_ip; /* Target process instruction pointer */
uc = _UNW_createContext(my_mem_reader, my_dlmodule_info,1);
if (_UNW_getAlertCode(uc) == _UNW_MEMORY_ALLOCATION_ERROR) {
/* Code to notify user of low memory problem */
}
/* Example use of the _Unwind_Context * follows: */
if ((retcode = _UNW_setIP(uc,target_ip)) != _UNW_OK) {
/* Notify user: Initialization problem */
} AUTHOR_UNW_createContextForSelf,
_UNW_createContext,
and
_UNW_destroyContext
were developed by HP.
|