support print crash callstack for aarch64
This commit is contained in:
17
deps/oblib/src/lib/signal/ob_libunwind.c
vendored
17
deps/oblib/src/lib/signal/ob_libunwind.c
vendored
@ -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
|
||||
|
||||
15
deps/oblib/src/lib/signal/ob_signal_handlers.cpp
vendored
15
deps/oblib/src/lib/signal/ob_signal_handlers.cpp
vendored
@ -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);
|
||||
|
||||
32
deps/oblib/src/lib/signal/ob_signal_utils.cpp
vendored
32
deps/oblib/src/lib/signal/ob_signal_utils.cpp
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
6
deps/oblib/src/lib/signal/ob_signal_utils.h
vendored
6
deps/oblib/src/lib/signal/ob_signal_utils.h
vendored
@ -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_
|
||||
|
||||
9
deps/oblib/src/lib/utility/ob_backtrace.cpp
vendored
9
deps/oblib/src/lib/utility/ob_backtrace.cpp
vendored
@ -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) &&
|
||||
|
||||
1
deps/oblib/src/lib/utility/ob_backtrace.h
vendored
1
deps/oblib/src/lib/utility/ob_backtrace.h
vendored
@ -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) \
|
||||
({ \
|
||||
|
||||
Reference in New Issue
Block a user