1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
.\" *********************************** start of \input{common.tex}
.\" *********************************** end of \input{common.tex}
'\" t
.\" Manual page created with latex2man on Tue Aug 29 10:53:41 2023
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
.nf
..
.de Ve
.ft R
.fi
..
.TH "LIBUNWIND\-NTO" "3libunwind" "29 August 2023" "Programming Library " "Programming Library "
.SH NAME
libunwind\-nto
\-\- QNX Neutrino support in libunwind
.SH SYNOPSIS
.PP
#include <libunwind\-nto.h>
.br
.PP
unw_accessors_t
unw_nto_accessors;
.br
.PP
void *unw_nto_create(pid_t,
pthread_t);
.br
void unw_nto_destroy(void *);
.br
.PP
int
unw_nto_find_proc_info(unw_addr_space_t,
unw_word_t,
unw_proc_info_t *,
int,
void *);
.br
void
unw_nto_put_unwind_info(unw_addr_space_t,
unw_proc_info_t *,
void *);
.br
int
unw_nto_get_dyn_info_list_addr(unw_addr_space_t,
unw_word_t *,
void *);
.br
int
unw_nto_access_mem(unw_addr_space_t,
unw_word_t,
unw_word_t *,
int,
void *);
.br
int
unw_nto_access_reg(unw_addr_space_t,
unw_regnum_t,
unw_word_t *,
int,
void *);
.br
int
unw_nto_access_fpreg(unw_addr_space_t,
unw_regnum_t,
unw_fpreg_t *,
int,
void *);
.br
int
unw_nto_get_proc_name(unw_addr_space_t,
unw_word_t,
char *,
size_t,
unw_word_t *,
void *);
.br
int
unw_nto_resume(unw_addr_space_t,
unw_cursor_t *,
void *);
.br
.PP
.SH DESCRIPTION
.PP
The QNX operating system makes it possible for a process to
gain access to the machine state and virtual memory of \fIanother\fP
process, or a different thread within the same process.
gain access to the machine state and virtual memory of \fIanother\fP
it is possible to hook up libunwind
to another process.
While it\&'s not very difficult to do so directly,
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 unw_nto,
which is stands for ``unwind\-via\-nto\&''\&.
.PP
An application that wants to use the libunwind
NTO remote needs
to take the following steps.
.PP
.TP
1.
Create a new libunwind address\-space that represents the target
process and thread. This is done by calling
unw_create_addr_space().
In many cases, the application will
simply want to pass the address of unw_nto_accessors
as the
first argument to this routine. Doing so will ensure that
libunwind
will be able to properly unwind the target process.
.PP
.TP
2.
Create an NTO info structure by calling 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.
.PP
.TP
3.
The opaque pointer returned then needs to be passed as the
``argument\&'' pointer (third argument) to unw_init_remote().
.PP
When the application is done using libunwind
on the target process,
unw_nto_destroy()
needs to be called, passing it the opaque pointer
that was returned by the call to unw_nto_create().
This ensures that
all memory and other resources are freed up.
.PP
The unw_nto_resume()
is not supported on the NTO remote.
.PP
In special circumstances, an application may prefer to use
only portions of the libunwind
NTO remote. For this reason, the
individual callback routines (unw_nto_find_proc_info(),
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 unw_nto_accessors,
but doing so would prevent static
initialization. Also, when using unw_nto_accessors,
\fIall\fP
the callback routines will be linked into the application, even if
they are never actually called.
.PP
.SH THREAD SAFETY
.PP
The libunwind
NTO remote assumes that a single 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.
.PP
.SH RETURN VALUE
.PP
unw_nto_create()
may return a NULL if it fails
to create the NTO info structure for any reason.
.PP
.SH FILES
.PP
.TP
libunwind\-nto.h
Headerfile to include when using the
interface defined by this library.
.TP
\fB\-l\fPunwind\-nto \fB\-l\fPunwind\-generic
Linker\-switches to add when building a program that uses the
functions defined by this library.
.PP
.SH EXAMPLE
.Vb
#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);
}
.Ve
.PP
.SH SEE ALSO
libunwind(3libunwind)
.PP
.\" NOTE: This file is generated, DO NOT EDIT.
|