[CP] CRASH ERROR improve

This commit is contained in:
tushicheng
2024-02-04 09:12:28 +00:00
committed by ob-robot
parent 5e08668e62
commit 6acb97c9f6
9 changed files with 30 additions and 258 deletions

View File

@ -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
)

View File

@ -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;

View File

@ -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";

View File

@ -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';
}

View File

@ -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) {

View File

@ -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'; \

View File

@ -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;
}

View File

@ -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_