diff --git a/deps/oblib/src/lib/signal/ob_libunwind.c b/deps/oblib/src/lib/signal/ob_libunwind.c index 71e00c1636..118d348fe5 100644 --- a/deps/oblib/src/lib/signal/ob_libunwind.c +++ b/deps/oblib/src/lib/signal/ob_libunwind.c @@ -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 diff --git a/deps/oblib/src/lib/signal/ob_signal_handlers.cpp b/deps/oblib/src/lib/signal/ob_signal_handlers.cpp index f0b3ca7325..1a0a8cfd1a 100644 --- a/deps/oblib/src/lib/signal/ob_signal_handlers.cpp +++ b/deps/oblib/src/lib/signal/ob_signal_handlers.cpp @@ -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); diff --git a/deps/oblib/src/lib/signal/ob_signal_utils.cpp b/deps/oblib/src/lib/signal/ob_signal_utils.cpp index 56680d73b3..97209c6ee5 100644 --- a/deps/oblib/src/lib/signal/ob_signal_utils.cpp +++ b/deps/oblib/src/lib/signal/ob_signal_utils.cpp @@ -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); + } +} diff --git a/deps/oblib/src/lib/signal/ob_signal_utils.h b/deps/oblib/src/lib/signal/ob_signal_utils.h index 4700ef81c8..75c8b9966f 100644 --- a/deps/oblib/src/lib/signal/ob_signal_utils.h +++ b/deps/oblib/src/lib/signal/ob_signal_utils.h @@ -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_ diff --git a/deps/oblib/src/lib/utility/ob_backtrace.cpp b/deps/oblib/src/lib/utility/ob_backtrace.cpp index 6b7bfbe64e..b0605d4666 100644 --- a/deps/oblib/src/lib/utility/ob_backtrace.cpp +++ b/deps/oblib/src/lib/utility/ob_backtrace.cpp @@ -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) && diff --git a/deps/oblib/src/lib/utility/ob_backtrace.h b/deps/oblib/src/lib/utility/ob_backtrace.h index d962daa433..f1efa9d2bc 100644 --- a/deps/oblib/src/lib/utility/ob_backtrace.h +++ b/deps/oblib/src/lib/utility/ob_backtrace.h @@ -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) \ ({ \