support print crash callstack for aarch64

This commit is contained in:
obdev
2024-05-14 06:02:07 +00:00
committed by ob-robot
parent 5b1fa87e45
commit 6b091aa36a
6 changed files with 58 additions and 22 deletions

View File

@ -21,6 +21,7 @@ static int safe_backtrace_(unw_context_t *context, char *buf, int64_t len, int64
static ssize_t get_stack_trace_inplace(unw_context_t *context, unw_cursor_t *cursor,
uintptr_t *addresses, size_t max_addresses);
static int8_t get_frame_info(unw_cursor_t *cursor, uintptr_t *ip);
extern int64_t safe_parray_c(char *buf, int64_t len, int64_t *array, int size);
int safe_backtrace(char *buf, int64_t len, int64_t *pos)
{
@ -34,7 +35,6 @@ int safe_backtrace(char *buf, int64_t len, int64_t *pos)
return ret;
}
extern int64_t get_rel_offset_c(int64_t addr);
static int safe_backtrace_(unw_context_t *context, char *buf, int64_t len,
int64_t *pos)
{
@ -46,19 +46,7 @@ static int safe_backtrace_(unw_context_t *context, char *buf, int64_t len,
if (n < 0) {
ret = -1;
} else {
for (int i = 0; i < n; i++) {
int64_t addr = get_rel_offset_c(addrs[i]);
int count = lnprintf(buf + *pos, len - *pos, "0x%lx", addr);
count++; // for space
if (count > 0 && *pos + count < len) {
*pos += count;
buf[*pos - 1] = ' ';
} else {
// buf not enough
break;
}
}
--*pos;
*pos += safe_parray_c(buf + *pos, len - *pos, (int64_t*)addrs, n);
}
buf[*pos] = '\0';
return ret;
@ -109,4 +97,5 @@ int8_t get_frame_info(unw_cursor_t *cursor, uintptr_t *ip)
*ip = uip - (r == 0);
return 1;
}
#endif

View File

@ -185,12 +185,8 @@ void coredump_cb(volatile int sig, volatile int sig_code, void* volatile sig_add
char tname[16];
prctl(PR_GET_NAME, tname);
// backtrace
char bt[512];
char bt[512] = {'\0'};
int64_t len = 0;
#ifdef __x86_64__
safe_backtrace(bt, sizeof(bt) - 1, &len);
#endif
bt[len++] = '\0';
// extra
const ObFatalErrExtraInfoGuard *extra_info = nullptr; // TODO: May deadlock, ObFatalErrExtraInfoGuard::get_thd_local_val_ptr();
auto *trace_id = ObCurTraceId::get_trace_id();
@ -206,11 +202,18 @@ void coredump_cb(volatile int sig, volatile int sig_code, void* volatile sig_add
#if defined(__x86_64__)
int64_t ip = con->uc_mcontext.gregs[REG_RIP];
int64_t bp = con->uc_mcontext.gregs[REG_RBP]; // stack base
safe_backtrace(bt, sizeof(bt) - 1, &len);
#elif defined(__aarch64__)
int64_t ip = con->uc_mcontext.regs[30];
int64_t bp = con->uc_mcontext.regs[29];
void* addrs[64];
int n_addr = light_backtrace(addrs, ARRAYSIZEOF(addrs), bp);
len += safe_parray(bt, sizeof(bt) - 1, (int64_t*)addrs, n_addr);
#else
// TODO: ARM
int64_t ip = -1;
int64_t bp = -1;
#endif
bt[len++] = '\0';
char rlimit_core[32] = "unlimited";
if (UINT64_MAX != g_rlimit_core) {
lnprintf(rlimit_core, sizeof(rlimit_core), "%lu", g_rlimit_core);

View File

@ -22,6 +22,7 @@
extern "C" {
extern int ob_poll(struct pollfd *__fds, nfds_t __nfds, int __timeout);
extern int64_t get_rel_offset_c(int64_t addr);
};
namespace oceanbase
@ -188,5 +189,36 @@ int wait_readable(int fd, int64_t timeout)
return ret;
}
int64_t safe_parray(char *buf, int64_t len, int64_t *array, int size)
{
int64_t pos = 0;
if (NULL != buf && len > 0 && NULL != array) {
int64_t count = 0;
for (int64_t i = 0; i < size; i++) {
int64_t addr = get_rel_offset_c(array[i]);
if (0 == i) {
count = lnprintf(buf + pos, len - pos, "0x%lx", addr);
} else {
count = lnprintf(buf + pos, len - pos, " 0x%lx", addr);
}
if (count >= 0 && pos + count < len) {
pos += count;
} else {
// buf not enough
break;
}
}
buf[pos] = 0;
}
return pos;
}
} // namespace common
} // namespace oceanbase
extern "C" {
int64_t safe_parray_c(char *buf, int64_t len, int64_t *array, int size)
{
return oceanbase::common::safe_parray(buf, len, array, size);
}
}

View File

@ -133,7 +133,13 @@ void safe_current_datetime_str_v2(char *buf, int64_t len, int64_t &pos);
int wait_readable(int fd, int64_t timeout);
int64_t safe_parray(char *buf, int64_t len, int64_t *array, int size);
} // namespace common
} // namespace oceanbase
extern "C" {
int64_t safe_parray_c(char *buf, int64_t len, int64_t *array, int size);
}
#endif // OCEANBASE_SIGNAL_UTILS_H_

View File

@ -28,16 +28,21 @@ namespace oceanbase
namespace common
{
int light_backtrace(void **buffer, int size)
{
return light_backtrace(buffer, size, (int64_t)__builtin_frame_address(0));
}
int light_backtrace(void **buffer, int size, int64_t rbp)
{
int rv = 0;
if (rv < size) {
buffer[rv++] = (void*)light_backtrace;
int (*fp)(void**, int, int64_t) = light_backtrace;
buffer[rv++] = (void*)fp;
}
void *stack_addr = nullptr;
size_t stack_size = 0;
if (OB_LIKELY(OB_SUCCESS == get_stackattr(stack_addr, stack_size))) {
#define addr_in_stack(addr) (addr >= (int64_t)stack_addr && addr < (int64_t)stack_addr + stack_size)
int64_t rbp = (int64_t)__builtin_frame_address(0);
while (rbp != 0 && rv < size) {
if (!addr_in_stack(*(int64_t*)rbp) &&
!FALSE_IT(rbp += 16) &&

View File

@ -22,6 +22,7 @@ void init_proc_map_info();
extern bool g_enable_backtrace;
const int64_t LBT_BUFFER_LENGTH = 1024;
int light_backtrace(void **buffer, int size);
int light_backtrace(void **buffer, int size, int64_t rbp);
// save one layer of call stack
#define ob_backtrace(buffer, size) \
({ \