
- use libunwrap which seems to be industry standard - display traceback on console if running interactive or with syslog disabled (color output unless nocolor specified) - print hexdump of offending code - print library filename for each stack frame Type: improvement Change-Id: I61d3056251b87076be0578ccda300aa311c222ef Signed-off-by: Damjan Marion <damarion@cisco.com>
76 lines
1.5 KiB
C
76 lines
1.5 KiB
C
/* SPDX-License-Identifier: Apache-2.0
|
|
* Copyright (c) 2024 Cisco Systems, Inc.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
#include <dlfcn.h>
|
|
|
|
#include <vppinfra/clib.h>
|
|
#include <vppinfra/stack.h>
|
|
#include <vppinfra/error.h>
|
|
|
|
#if HAVE_LIBUNWIND == 1
|
|
|
|
#define UNW_LOCAL_ONLY
|
|
#include <libunwind.h>
|
|
|
|
static __thread unw_cursor_t cursor;
|
|
static __thread unw_context_t context;
|
|
|
|
#endif
|
|
|
|
__clib_export clib_stack_frame_t *
|
|
clib_stack_frame_get (clib_stack_frame_t *sf)
|
|
{
|
|
#if HAVE_LIBUNWIND == 1
|
|
Dl_info info = {};
|
|
|
|
if (sf->index == 0)
|
|
{
|
|
if (unw_getcontext (&context) < 0)
|
|
{
|
|
clib_warning ("libunwind: cannot get local machine state\n");
|
|
return 0;
|
|
}
|
|
if (unw_init_local (&cursor, &context) < 0)
|
|
{
|
|
clib_warning (
|
|
"libunwind: cannot initialize cursor for local unwinding\n");
|
|
return 0;
|
|
}
|
|
if (unw_step (&cursor) < 1)
|
|
return 0;
|
|
}
|
|
else if (unw_step (&cursor) < 1)
|
|
return 0;
|
|
|
|
if (unw_get_reg (&cursor, UNW_REG_IP, &sf->ip))
|
|
{
|
|
clib_warning ("libunwind: cannot read IP\n");
|
|
return 0;
|
|
}
|
|
|
|
if (unw_get_reg (&cursor, UNW_REG_SP, &sf->sp))
|
|
{
|
|
clib_warning ("libunwind: cannot read SP\n");
|
|
return 0;
|
|
}
|
|
|
|
if (unw_get_proc_name (&cursor, sf->name, sizeof (sf->name), &sf->offset) <
|
|
0)
|
|
sf->name[0] = sf->offset = 0;
|
|
|
|
sf->is_signal_frame = unw_is_signal_frame (&cursor) ? 1 : 0;
|
|
|
|
if (dladdr ((void *) sf->ip, &info))
|
|
sf->file_name = info.dli_fname;
|
|
else
|
|
sf->file_name = 0;
|
|
|
|
sf->index++;
|
|
return sf;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|