mirror of
https://github.com/libunwind/libunwind.git
synced 2026-01-12 00:04:03 +08:00
It's a convention that unadorned section 3 man pages are libc functions and other libraries adorn the section name. Also added example code to the ptrace and nto remotes and fixed some unusual Engish-language constructs. Regenerated all man pages from their LaTEX sources.
184 lines
6.8 KiB
TeX
184 lines
6.8 KiB
TeX
\documentclass{article}
|
|
\usepackage[fancyhdr,pdf]{latex2man}
|
|
|
|
\input{common.tex}
|
|
|
|
\begin{document}
|
|
|
|
\begin{Name}{3libunwind}{libunwind-nto}{Blackberry}{Programming Library}{QNX Neutrino remote for libunwind}libunwind-nto -- QNX Neutrino support in libunwind
|
|
\end{Name}
|
|
\section{Synopsis}
|
|
|
|
\File{\#include $<$libunwind-nto.h$>$}\\
|
|
|
|
\noindent
|
|
\Type{unw\_accessors\_t} \Var{unw\_nto\_accessors};\\
|
|
|
|
\Type{void~*}\Func{unw\_nto\_create}(\Type{pid\_t}, \Type{pthread\_t});\\
|
|
\noindent
|
|
\Type{void}~\Func{unw\_nto\_destroy}(\Type{void~*});\\
|
|
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_find\_proc\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_proc\_info\_t~*}, \Type{int}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{void} \Func{unw\_nto\_put\_unwind\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_proc\_info\_t~*}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_access\_mem}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_access\_reg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_access\_fpreg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*}, \Type{int}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_get\_proc\_name}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\
|
|
\noindent
|
|
\Type{int} \Func{unw\_nto\_resume}(\Type{unw\_addr\_space\_t}, \Type{unw\_cursor\_t~*}, \Type{void~*});\\
|
|
|
|
\section{Description}
|
|
|
|
The QNX operating system makes it possible for a process to
|
|
gain access to the machine state and virtual memory of \emph{another}
|
|
process, or a different thread within the same process.
|
|
gain access to the machine state and virtual memory of \emph{another}
|
|
it is possible to hook up \Prog{libunwind} to another process.
|
|
While it's not very difficult to do so directly,
|
|
\Prog{libunwind} further facilitates this task by providing
|
|
ready-to-use callbacks for this purpose.
|
|
The routines and variables
|
|
implementing this facility use a name prefix of \Func{unw\_nto},
|
|
which is stands for ``unwind-via-nto''.
|
|
|
|
An application that wants to use the \Prog{libunwind} NTO remote needs
|
|
to take the following steps.
|
|
\begin{enumerate}
|
|
|
|
\item Create a new \Prog{libunwind} address-space that represents the target
|
|
process and thread. This is done by calling
|
|
\Func{unw\_create\_addr\_space}(). In many cases, the application will
|
|
simply want to pass the address of \Var{unw\_nto\_accessors} as the
|
|
first argument to this routine. Doing so will ensure that
|
|
\Prog{libunwind} will be able to properly unwind the target process.
|
|
|
|
\item Create an NTO info structure by calling \Func{unw\_nto\_create}(),
|
|
passing the pid and tid of the target process thread as the arguments.
|
|
This will stop the target thread. The process ID (pid) of the target
|
|
process must be known, and only a single thread can be unwound at a time
|
|
so the thread ID (tid) must also be specified.
|
|
|
|
\item The opaque pointer returned then needs to be passed as the
|
|
``argument'' pointer (third argument) to \Func{unw\_init\_remote}().
|
|
|
|
\end{enumerate}
|
|
|
|
When the application is done using \Prog{libunwind} on the target process,
|
|
\Func{unw\_nto\_destroy}() needs to be called, passing it the opaque pointer
|
|
that was returned by the call to \Func{unw\_nto\_create}(). This ensures that
|
|
all memory and other resources are freed up.
|
|
|
|
The \Func{unw\_nto\_resume}() is not supported on the NTO remote.
|
|
|
|
In special circumstances, an application may prefer to use
|
|
only portions of the \Prog{libunwind} NTO remote. For this reason, the
|
|
individual callback routines (\Func{unw\_nto\_find\_proc\_info}(),
|
|
\Func{unw\_nto\_put\_unwind\_info}(), etc.) are also available for direct
|
|
use. Of course, the addresses of these routines could also be picked
|
|
up from \Var{unw\_nto\_accessors}, but doing so would prevent static
|
|
initialization. Also, when using \Var{unw\_nto\_accessors}, \emph{all}
|
|
the callback routines will be linked into the application, even if
|
|
they are never actually called.
|
|
|
|
\section{Thread Safety}
|
|
|
|
The \Prog{libunwind} NTO remote assumes that a single \Prog{unw\_nto}-info
|
|
structure is never shared between threads of the unwinding program.
|
|
Because of this,
|
|
no explicit locking is used.
|
|
As long as only one thread uses an NTO info structure at any given time,
|
|
this facility is thread-safe.
|
|
|
|
\section{Return Value}
|
|
|
|
\Func{unw\_nto\_create}() may return a NULL if it fails
|
|
to create the NTO info structure for any reason.
|
|
|
|
\section{Files}
|
|
|
|
\begin{Description}
|
|
\item[\File{libunwind-nto.h}] Headerfile to include when using the
|
|
interface defined by this library.
|
|
\item[\Opt{-l}\File{unwind-nto} \Opt{-l}\File{unwind-generic}]
|
|
Linker-switches to add when building a program that uses the
|
|
functions defined by this library.
|
|
\end{Description}
|
|
|
|
\section{Example}
|
|
\begin{verbatim}
|
|
#include <libunwind-nto.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
if (argc != 2) {
|
|
fprintf (stderr, "usage: %s PID\n", argv[0]);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
char *endptr;
|
|
pid_t target_pid = strtoul (argv[1], &endptr, 10);
|
|
if (target_pid == 0 && argv[1] == endptr) {
|
|
fprintf (stderr, "usage: %s PID\n", argv[0]);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
unw_addr_space_t as = unw_create_addr_space (&unw_nto_accessors, 0);
|
|
if (!as) {
|
|
fprintf (stderr, "unw_create_addr_space() failed");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
void *ui = unw_nto_create (target_pid, (thread_t)1);
|
|
if (!ui) {
|
|
fprintf (stderr, "unw_nto_create() failed");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
unw_cursor_t cursor;
|
|
int ret = unw_init_remote (&cursor, as, ui);
|
|
if (ret < 0) {
|
|
fprintf (stderr, "unw_init_remote() failed: ret=%d\n", ret);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
do {
|
|
unw_proc_info_t pi;
|
|
ret = unw_get_proc_info (&cursor, &pi);
|
|
if (ret == -UNW_ENOINFO) {
|
|
fprintf (stdout, "no info\n");
|
|
} else if (ret >= 0) {
|
|
printf ("\tproc=%#016lx-%#016lx\thandler=%#016lx lsda=%#016lx",
|
|
(long) pi.start_ip, (long) pi.end_ip,
|
|
(long) pi.handler, (long) pi.lsda);
|
|
}
|
|
ret = unw_step (&cursor);
|
|
} while (ret > 0);
|
|
if (ret < 0) {
|
|
fprintf (stderr, "unwind failed with ret=%d\n", ret);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
unw_nto_destroy (ui);
|
|
unw_destroy_addr_space (as);
|
|
exit (EXIT_SUCCESS);
|
|
}
|
|
\end{verbatim}
|
|
|
|
\section{See Also}
|
|
\SeeAlso{libunwind}(3libunwind)
|
|
|
|
\LatexManEnd
|
|
|
|
\end{document}
|