Doing a BT_SELF backtrace in a signal handler

Updated: April 19, 2023

Providing backtracing that's signal-handler-safe is a special case. From within a signal handler, you can use only bt_get_backtrace(), and you must ensure access to memory is without conflict. For example:

bt_accessor_t acc_sighandler1;
bt_addr_t pc_sighandler1[10];
int count_sighandler1;
bt_accessor_t acc;
bt_memmap_t memmap;
  
void sighandler1(int sig)
{
    count_sighandler1 =
        bt_get_backtrace(&acc_sighandler1, pc_sighandler1,
           sizeof(pc_sighandler1) / sizeof(bt_addr_t));
}

thread_func()
{
    char out[512];
    if (bt_init_accessor(&acc_sighandler1, BT_SELF) == -1)
    {
      fprintf( stderr, "%s:%i %s (%i)%s\n", __FUNCTION__, __LINE__,
               "bt_init_accessor", errno, strerror(errno));
      ...
    }

    signal(SIGUSR2, sighandler1);
    ...
    if (bt_sprnf_addrs( &memmap, pc_sighandler1, count_sighandler1, "%a",
                        out, sizeof(out), 0) == -1)
    {
       fprintf( stderr, "%s:%i %s (%i)%s\n", __FUNCTION__, __LINE__,
                "bt_sprnf_addrs", errno, strerror(errno));
       ...
    }
    ...

    if (bt_release_accessor(&acc) == -1)
    {
       fprintf( stderr, "%s:%i %s (%i)%s\n", __FUNCTION__, __LINE__,
                "bt_release_accessor", errno, strerror(errno));
       ...
    }
    ...
}