[CP] CRASH ERROR improve
This commit is contained in:
1
deps/oblib/src/lib/CMakeLists.txt
vendored
1
deps/oblib/src/lib/CMakeLists.txt
vendored
@ -232,7 +232,6 @@ ob_set_subtarget(oblib_lib signal
|
||||
signal/ob_signal_struct.cpp
|
||||
signal/ob_signal_utils.cpp
|
||||
signal/ob_signal_worker.cpp
|
||||
signal/safe_snprintf.c
|
||||
signal/ob_libunwind.c
|
||||
)
|
||||
|
||||
|
||||
4
deps/oblib/src/lib/signal/ob_libunwind.c
vendored
4
deps/oblib/src/lib/signal/ob_libunwind.c
vendored
@ -12,9 +12,9 @@
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "lib/signal/ob_libunwind.h"
|
||||
#include "lib/signal/safe_snprintf.h"
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
#include "util/easy_string.h"
|
||||
|
||||
static const int MAX_BT_ADDRESS_CNT = 100;
|
||||
static int safe_backtrace_(unw_context_t *context, char *buf, int64_t len, int64_t *pos);
|
||||
@ -48,7 +48,7 @@ static int safe_backtrace_(unw_context_t *context, char *buf, int64_t len,
|
||||
} else {
|
||||
for (int i = 0; i < n; i++) {
|
||||
int64_t addr = get_rel_offset_c(addrs[i]);
|
||||
int count = safe_snprintf(buf + *pos, len - *pos, "0x%lx", addr);
|
||||
int count = lnprintf(buf + *pos, len - *pos, "0x%lx", addr);
|
||||
count++; // for space
|
||||
if (count > 0 && *pos + count < len) {
|
||||
*pos += count;
|
||||
|
||||
38
deps/oblib/src/lib/signal/ob_signal_handlers.cpp
vendored
38
deps/oblib/src/lib/signal/ob_signal_handlers.cpp
vendored
@ -81,9 +81,9 @@ signal_handler_t &get_signal_handler()
|
||||
bool g_redirect_handler = false;
|
||||
static __thread int g_coredump_num = 0;
|
||||
|
||||
#define COMMON_FMT "timestamp=%ld, tid=%ld, tname=%s, trace_id=%lu-%lu-%lu-%lu, extra_info=(%s), lbt=%s"
|
||||
#define COMMON_FMT "timestamp=%ld, tid=%ld, tname=%s, trace_id="TRACE_ID_FORMAT_V2", extra_info=(%s), lbt=%s"
|
||||
|
||||
void coredump_cb(int, siginfo_t*, void*);
|
||||
void coredump_cb(int, int, void*, void*);
|
||||
void ob_signal_handler(int sig, siginfo_t *si, void *context)
|
||||
{
|
||||
if (!g_redirect_handler) {
|
||||
@ -98,7 +98,7 @@ void ob_signal_handler(int sig, siginfo_t *si, void *context)
|
||||
if (ctx.req_id_ != req_id) return;
|
||||
ctx.handler_->handle(ctx);
|
||||
} else {
|
||||
coredump_cb(sig, si, context);
|
||||
coredump_cb(sig, si->si_code, si->si_addr, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ void ob_signal_handler(int sig, siginfo_t *si, void *context)
|
||||
void hook_sigsegv_msg(int sig, siginfo_t *si, void *context)
|
||||
{
|
||||
if (mprotect_page(si->si_addr, 8, PROT_READ | PROT_WRITE, "release signal addr") != 0) {
|
||||
coredump_cb(sig, si, context);
|
||||
coredump_cb(sig, si->si_code, si->si_addr, context);
|
||||
} else {
|
||||
// thread_name
|
||||
char tname[16];
|
||||
@ -126,18 +126,18 @@ void close_socket_fd()
|
||||
int fd = -1;
|
||||
int pid = getpid();
|
||||
|
||||
safe_snprintf(path, 32, "/proc/%d/fd/", pid);
|
||||
lnprintf(path, 32, "/proc/%d/fd/", pid);
|
||||
if (NULL == (dir = opendir(path))) {
|
||||
} else {
|
||||
while(NULL != (fd_file = readdir(dir))) {
|
||||
if (0 != strcmp(fd_file->d_name, ".") && 0 != strcmp(fd_file->d_name, "..")
|
||||
&& 0 != strcmp(fd_file->d_name, "0") && 0 != strcmp(fd_file->d_name, "1")
|
||||
&& 0 != strcmp(fd_file->d_name, "2")) {
|
||||
safe_snprintf(name, 32, "/proc/%d/fd/%s", pid, fd_file->d_name);
|
||||
lnprintf(name, 32, "/proc/%d/fd/%s", pid, fd_file->d_name);
|
||||
if (-1 == readlink(name, real_name, 32)) {
|
||||
DLOG(INFO, "[CLOSEFD], err read link %s, errno = %d", name, errno);
|
||||
} else {
|
||||
safe_snprintf(name, 32, "%s", real_name);
|
||||
lnprintf(name, 32, "%s", real_name);
|
||||
if (NULL != strstr(name, "socket")) {
|
||||
fd = atoi(fd_file->d_name);
|
||||
close(fd);
|
||||
@ -153,7 +153,7 @@ void close_socket_fd()
|
||||
}
|
||||
|
||||
|
||||
void coredump_cb(int sig, siginfo_t *si, void *context)
|
||||
void coredump_cb(volatile int sig, volatile int sig_code, void* volatile sig_addr, void *context)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (g_coredump_num++ < 1) {
|
||||
@ -170,7 +170,7 @@ void coredump_cb(int sig, siginfo_t *si, void *context)
|
||||
char tname[16];
|
||||
prctl(PR_GET_NAME, tname);
|
||||
// backtrace
|
||||
char bt[256];
|
||||
char bt[512];
|
||||
int64_t len = 0;
|
||||
#ifdef __x86_64__
|
||||
safe_backtrace(bt, sizeof(bt) - 1, &len);
|
||||
@ -183,7 +183,7 @@ void coredump_cb(int sig, siginfo_t *si, void *context)
|
||||
if (trace_id != nullptr) {
|
||||
trace_id->get_uval(uval);
|
||||
}
|
||||
char print_buf[512];
|
||||
char print_buf[1024];
|
||||
const ucontext_t *con = (ucontext_t *)context;
|
||||
#if defined(__x86_64__)
|
||||
int64_t ip = con->uc_mcontext.gregs[REG_RIP];
|
||||
@ -195,20 +195,20 @@ void coredump_cb(int sig, siginfo_t *si, void *context)
|
||||
#endif
|
||||
char rlimit_core[32] = "unlimited";
|
||||
if (UINT64_MAX != g_rlimit_core) {
|
||||
safe_snprintf(rlimit_core, sizeof(rlimit_core), "%lu", g_rlimit_core);
|
||||
lnprintf(rlimit_core, sizeof(rlimit_core), "%lu", g_rlimit_core);
|
||||
}
|
||||
char crash_info[128] = "CRASH ERROR!!!";
|
||||
int64_t fatal_error_thread_id = get_fatal_error_thread_id();
|
||||
if (-1 != fatal_error_thread_id) {
|
||||
safe_snprintf(crash_info, sizeof(crash_info),
|
||||
"Right to Die or Duty to Live's Thread Existed before CRASH ERROR!!!"
|
||||
"ThreadId=%ld,", fatal_error_thread_id);
|
||||
lnprintf(crash_info, sizeof(crash_info),
|
||||
"Right to Die or Duty to Live's Thread Existed before CRASH ERROR!!!"
|
||||
"ThreadId=%ld,", fatal_error_thread_id);
|
||||
}
|
||||
ssize_t print_len = safe_snprintf(print_buf, sizeof(print_buf),
|
||||
"%s IP=%lx, RBP=%lx, sig=%d, sig_code=%d, sig_addr=%p, RLIMIT_CORE=%s, "COMMON_FMT", ",
|
||||
crash_info, ip, bp, sig, si->si_code, si->si_addr, rlimit_core,
|
||||
ts, GETTID(), tname, uval[0], uval[1], uval[2], uval[3],
|
||||
(NULL == extra_info) ? NULL : to_cstring(*extra_info), bt);
|
||||
ssize_t print_len = lnprintf(print_buf, sizeof(print_buf),
|
||||
"%s IP=%lx, RBP=%lx, sig=%d, sig_code=%d, sig_addr=%p, RLIMIT_CORE=%s, "COMMON_FMT", ",
|
||||
crash_info, ip, bp, sig, sig_code, sig_addr, rlimit_core,
|
||||
ts, GETTID(), tname, TRACE_ID_FORMAT_PARAM(uval),
|
||||
(NULL == extra_info) ? NULL : to_cstring(*extra_info), bt);
|
||||
const auto &si_guard = ObSqlInfoGuard::get_cur_guard();
|
||||
char sql[] = "SQL=";
|
||||
char end[] = "\n";
|
||||
|
||||
@ -31,7 +31,7 @@ ObSigBTOnlyProcessor::ObSigBTOnlyProcessor()
|
||||
{
|
||||
char *buf = filename_;
|
||||
int64_t len = sizeof(filename_);
|
||||
int64_t pos = safe_snprintf(buf, len, "stack.%d.", getpid());
|
||||
int64_t pos = lnprintf(buf, len, "stack.%d.", getpid());
|
||||
int64_t count = 0;
|
||||
safe_current_datetime_str(buf + pos, len - pos, count);
|
||||
pos += count;
|
||||
@ -63,7 +63,7 @@ int ObSigBTOnlyProcessor::prepare()
|
||||
char tname[16];
|
||||
prctl(PR_GET_NAME, tname);
|
||||
int64_t count = 0;
|
||||
count = safe_snprintf(buf_ + pos_, len - pos_, "tid: %ld, tname: %s, lbt: ", tid, tname);
|
||||
count = lnprintf(buf_ + pos_, len - pos_, "tid: %ld, tname: %s, lbt: ", tid, tname);
|
||||
pos_ += count;
|
||||
#ifdef __x86_64__
|
||||
safe_backtrace(buf_ + pos_, len - pos_, &count);
|
||||
@ -91,7 +91,7 @@ int ObSigBTSQLProcessor::prepare()
|
||||
// TODO: save sql_
|
||||
int64_t len = sizeof(buf_) - 1;
|
||||
pos_--;
|
||||
int64_t count = safe_snprintf(buf_ + pos_, len - pos_, ", sql: TODO");
|
||||
int64_t count = lnprintf(buf_ + pos_, len - pos_, ", sql: TODO");
|
||||
pos_ += count;
|
||||
buf_[pos_++] = '\n';
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ void safe_current_datetime_str(char *buf, int64_t len, int64_t &pos)
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
struct tm tm;
|
||||
safe_secs_to_tm(ts.tv_sec, &tm);
|
||||
int64_t count = safe_snprintf(buf, len, "%d%d%d%d%d%d",
|
||||
int64_t count = lnprintf(buf, len, "%d%d%d%d%d%d",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
if (count >= 0 && count < len) {
|
||||
@ -156,7 +156,7 @@ void safe_current_datetime_str_v2(char *buf, int64_t len, int64_t &pos)
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
struct tm tm;
|
||||
safe_secs_to_tm(ts.tv_sec, &tm);
|
||||
int64_t count = safe_snprintf(buf, len, "%d-%d-%d %d:%d:%d.%ld",
|
||||
int64_t count = lnprintf(buf, len, "%d-%d-%d %d:%d:%d.%ld",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, (long)(ts.tv_nsec * 1e-3));
|
||||
if (count >= 0 && count < len) {
|
||||
|
||||
4
deps/oblib/src/lib/signal/ob_signal_utils.h
vendored
4
deps/oblib/src/lib/signal/ob_signal_utils.h
vendored
@ -23,11 +23,11 @@
|
||||
#include <fcntl.h>
|
||||
#include "lib/coro/co_var.h"
|
||||
#include "lib/signal/ob_signal_struct.h"
|
||||
#include "lib/signal/safe_snprintf.h"
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
#include "lib/ob_errno.h"
|
||||
#include "lib/utility/ob_defer.h"
|
||||
#include "lib/ob_abort.h"
|
||||
#include "util/easy_string.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -83,7 +83,7 @@ private:
|
||||
buf[pos] = '\0'; \
|
||||
static TLOCAL(ByteBuf<256>, log_buf); \
|
||||
int64_t tid = static_cast<int64_t>(syscall(__NR_gettid)); \
|
||||
ssize_t log_len = safe_snprintf(log_buf, sizeof(log_buf), DFMT(fmt), buf, #log_level, \
|
||||
ssize_t log_len = lnprintf(log_buf, sizeof(log_buf), DFMT(fmt), buf, #log_level, \
|
||||
__FUNCTION__, __FILENAME__, __LINE__, \
|
||||
tid, get_tl_trace_id().value(), ##args); \
|
||||
log_buf[sizeof(log_buf) - 1] = '\n'; \
|
||||
|
||||
179
deps/oblib/src/lib/signal/safe_snprintf.c
vendored
179
deps/oblib/src/lib/signal/safe_snprintf.c
vendored
@ -1,179 +0,0 @@
|
||||
// Copyright 2021 Alibaba Inc. All Rights Reserved.
|
||||
// Author:
|
||||
//
|
||||
|
||||
#include "lib/signal/safe_snprintf.h"
|
||||
static const char HEX[] = "0123456789abcdef";
|
||||
|
||||
static char *
|
||||
safe_utoa(int _base, uint64_t val, char *buf)
|
||||
{
|
||||
uint32_t base = (uint32_t) _base;
|
||||
*buf-- = 0;
|
||||
do {
|
||||
*buf-- = HEX[val % base];
|
||||
} while ((val /= base) != 0);
|
||||
return buf + 1;
|
||||
}
|
||||
|
||||
static char *
|
||||
safe_itoa(int base, int64_t val, char *buf)
|
||||
{
|
||||
char *orig_buf = buf;
|
||||
const int32_t is_neg = (val < 0);
|
||||
*buf-- = 0;
|
||||
|
||||
if (is_neg) {
|
||||
val = -val;
|
||||
}
|
||||
if (is_neg && base == 16) {
|
||||
int ix;
|
||||
val -= 1;
|
||||
for (ix = 0; ix < 16; ++ix)
|
||||
buf[-ix] = '0';
|
||||
}
|
||||
|
||||
do {
|
||||
*buf-- = HEX[val % base];
|
||||
} while ((val /= base) != 0);
|
||||
|
||||
if (is_neg && base == 10) {
|
||||
*buf-- = '-';
|
||||
}
|
||||
|
||||
if (is_neg && base == 16) {
|
||||
int ix;
|
||||
buf = orig_buf - 1;
|
||||
for (ix = 0; ix < 16; ++ix, --buf) {
|
||||
/* *INDENT-OFF* */
|
||||
switch (*buf) {
|
||||
case '0': *buf = 'f'; break;
|
||||
case '1': *buf = 'e'; break;
|
||||
case '2': *buf = 'd'; break;
|
||||
case '3': *buf = 'c'; break;
|
||||
case '4': *buf = 'b'; break;
|
||||
case '5': *buf = 'a'; break;
|
||||
case '6': *buf = '9'; break;
|
||||
case '7': *buf = '8'; break;
|
||||
case '8': *buf = '7'; break;
|
||||
case '9': *buf = '6'; break;
|
||||
case 'a': *buf = '5'; break;
|
||||
case 'b': *buf = '4'; break;
|
||||
case 'c': *buf = '3'; break;
|
||||
case 'd': *buf = '2'; break;
|
||||
case 'e': *buf = '1'; break;
|
||||
case 'f': *buf = '0'; break;
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
}
|
||||
return buf + 1;
|
||||
}
|
||||
|
||||
static const char *
|
||||
safe_check_longlong(const char *fmt, int32_t * have_longlong)
|
||||
{
|
||||
*have_longlong = 0;
|
||||
if (*fmt == 'l') {
|
||||
fmt++;
|
||||
if (*fmt != 'l') {
|
||||
*have_longlong = (sizeof(long) == sizeof(int64_t));
|
||||
} else {
|
||||
fmt++;
|
||||
*have_longlong = 1;
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
int
|
||||
_safe_vsnprintf(char *to, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
char *start = to;
|
||||
char *end = start + size - 1;
|
||||
for (; *format; ++format) {
|
||||
int32_t have_longlong = 0;
|
||||
if (*format != '%') {
|
||||
if (to == end) { /* end of buffer */
|
||||
break;
|
||||
}
|
||||
*to++ = *format; /* copy ordinary char */
|
||||
continue;
|
||||
}
|
||||
++format; /* skip '%' */
|
||||
|
||||
format = safe_check_longlong(format, &have_longlong);
|
||||
|
||||
switch (*format) {
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'p':
|
||||
{
|
||||
int64_t ival = 0;
|
||||
uint64_t uval = 0;
|
||||
if (*format == 'p')
|
||||
have_longlong = (sizeof(void *) == sizeof(uint64_t));
|
||||
if (have_longlong) {
|
||||
if (*format == 'u') {
|
||||
uval = va_arg(ap, uint64_t);
|
||||
} else {
|
||||
ival = va_arg(ap, int64_t);
|
||||
}
|
||||
} else {
|
||||
if (*format == 'u') {
|
||||
uval = va_arg(ap, uint32_t);
|
||||
} else {
|
||||
ival = va_arg(ap, int32_t);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char buff[22];
|
||||
const int base = (*format == 'x' || *format == 'p') ? 16 : 10;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
char *val_as_str = (*format == 'u') ?
|
||||
safe_utoa(base, uval, &buff[sizeof(buff) - 1]) :
|
||||
safe_itoa(base, ival, &buff[sizeof(buff) - 1]);
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* Strip off "ffffffff" if we have 'x' format without 'll' */
|
||||
if (*format == 'x' && !have_longlong && ival < 0) {
|
||||
val_as_str += 8;
|
||||
}
|
||||
|
||||
while (*val_as_str && to < end) {
|
||||
*to++ = *val_as_str++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
case 's':
|
||||
{
|
||||
const char *val = va_arg(ap, char *);
|
||||
if (!val) {
|
||||
val = "(null)";
|
||||
}
|
||||
while (*val && to < end) {
|
||||
*to++ = *val++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
return (int)(to - start);
|
||||
}
|
||||
|
||||
int
|
||||
_safe_snprintf(char *to, size_t n, const char *fmt, ...)
|
||||
{
|
||||
int result;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
result = _safe_vsnprintf(to, n, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
48
deps/oblib/src/lib/signal/safe_snprintf.h
vendored
48
deps/oblib/src/lib/signal/safe_snprintf.h
vendored
@ -1,48 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SAFE_SNPRINTF_H_
|
||||
#define OCEANBASE_SAFE_SNPRINTF_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/**
|
||||
A (very) limited version of snprintf.
|
||||
@param to Destination buffer.
|
||||
@param n Size of destination buffer.
|
||||
@param fmt printf() style format string.
|
||||
@returns Number of bytes written, including terminating '\0'
|
||||
Supports 'd' 'i' 'u' 'x' 'p' 's' conversion.
|
||||
Supports 'l' and 'll' modifiers for integral types.
|
||||
Does not support any width/precision.
|
||||
Implemented with simplicity, and async-signal-safety in mind.
|
||||
*/
|
||||
int _safe_vsnprintf(char *to, size_t size, const char *format, va_list ap);
|
||||
int _safe_snprintf(char *to, size_t n, const char *fmt, ...);
|
||||
|
||||
#define safe_snprintf(_s, _n, ...) \
|
||||
_safe_snprintf((char *)(_s), (size_t)(_n), __VA_ARGS__)
|
||||
|
||||
#define safe_vsnprintf(_s, _n, _f, _a) \
|
||||
_safe_vsnprintf((char *)(_s), (size_t)(_n), _f, _a)
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif // OCEANBASE_SAFE_SNPRINTF_H_
|
||||
Reference in New Issue
Block a user