---
name: "libunwind-nto"
section: "3libunwind"
platform: "linux"
package: "libunwind-dev"
version: "1.8.1-0.1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/libunwind-nto/3libunwind"
---

# libunwind-nto(3libunwind)

## NAME

libunwind-nto -- QNX Neutrino support in libunwind

## SYNOPSIS

\#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 \*);\

## DESCRIPTION

The QNX operating system makes it possible for a process to  gain access to the machine state and virtual memory of *another* process, or a different thread within the same process.  gain access to the machine state and virtual memory of *another* 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''.

An application that wants to use the libunwind NTO remote needs  to take the following steps.

- 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.

- 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.

- 3\.

  The opaque pointer returned then needs to be passed as the  \`\`argument'' pointer (third argument) to unw\_init\_remote().

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.

The unw\_nto\_resume() is not supported on the NTO remote.

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, *all* the callback routines will be linked into the application, even if  they are never actually called.

## THREAD SAFETY

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.

## RETURN VALUE

unw\_nto\_create() may return a NULL if it fails  to create the NTO info structure for any reason.

## FILES

- libunwind-nto.h

   Headerfile to include when using the  interface defined by this library.

- **-l**unwind-nto **-l**unwind-generic

   Linker-switches to add when building a program that uses the  functions defined by this library.

## 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);
    }
```

## SEE ALSO

libunwind(3libunwind)
