libunwind-nto
QNX SDP8.0C Library ReferenceAPIDeveloper
QNX OS support in the remote unwinder (libunwind)
Syntax:
#include libunwind-nto.h
unw_accessors_t unw_nto_accessors;
void *unw_nto_create(pid_t, pthread_t);
void unw_nto_destroy(void *);
int unw_nto_find_proc_info(unw_addr_space_t, unw_word_t,
unw_proc_info_t *, int, void *);
void unw_nto_put_unwind_info(unw_addr_space_t,
unw_proc_info_t *, void *);
int unw_nto_get_dyn_info_list_addr(unw_addr_space_t,
unw_word_t *, void *);
int unw_nto_access_mem(unw_addr_space_t, unw_word_t,
unw_word_t *, int, void *);
int unw_nto_access_reg(unw_addr_space_t, unw_regnum_t,
unw_word_t *, int, void *);
int unw_nto_access_fpreg(unw_addr_space_t, unw_regnum_t,
unw_fpreg_t *, int, void *);
int unw_nto_get_proc_name(unw_addr_space_t, unw_word_t,
char *, size_t, unw_word_t *, void *);
int unw_nto_resume(unw_addr_space_t, unw_cursor_t *, void *);
Runs on:
QNX
Description:
The QNX operating system allows a process to gain access to the machine state and virtual
memory of another process, or to a different thread within the same process. To accommodate
this access, the libunwind-nto library connects to another process using
callback routines. These callback routines and variables use the unw_nto name prefix,
which stands for "unwind via nto."
Using the unw_nto library:
To incorporate the unwind library into your application, use the following steps:
- Create a new libunwind address space to represent the target
process. To do so, call the unw_create_addr_space() routine, and:
- If the application passes the address of the
unw_nto_accessorscode as the first argument, then the target process unwinds properly. - If the application uses only portions of the unw_nto library,
then use the individual callback routines such as
unw_nto_find_proc_info(), or
unw_nto_put_unwind_info(). The addresses of these routines
get picked up from the
unw_nto_accessorscommand; this prevents static initialization and links the callback routines to the application without having to call them separately.
- If the application passes the address of the
- Locate the ID of the target process (pid). To unwind only one thread at a given time, locate the ID of that thread (tid).
- Create a unw_nto-info structure by calling the
unw_nto_create() function and passing the pid and
tid as the arguments. The application returns an opaque pointer.
Note:By specifying the tid of the target process thread, you ensure that only one thread uses the unw_nto-info structure at any given time, making the unwinding thread-safe.
- Call unw_init_remote(), passing the opaque pointer returned by unw_nto_create() as the third argument.
- When unwinding is complete, call unw_nto_destroy(), again passing the opaque pointer returned by unw_nto_create() as the argument, to ensure that all memory and other resources are freed up.
Application Programming Interface (API) for libunwind-nto:
- unw_nto_create()
- Creates a unw_nto-info structure when you pass the pid and tid of the
target process thread as the arguments. Doing this stops the target thread.
Returns an opaque pointer. May return NULL if the function fails to create the unw_nto-info structure.
- unw_nto_destroy()
- Frees up memory and other resources after the application runs the libunwind command on the target process.
- unw_nto_resume()
- Doesn't perform any action. May be called through unw_resume().
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Example:
#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);
}
Page updated:
