[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_
 | 
			
		||||
@ -12,10 +12,10 @@
 | 
			
		||||
 | 
			
		||||
#define USING_LOG_PREFIX SQL_ENG
 | 
			
		||||
#include "ob_expr_json_search.h"
 | 
			
		||||
#include "util/easy_string.h"
 | 
			
		||||
#include "sql/engine/expr/ob_expr_util.h"
 | 
			
		||||
#include "share/object/ob_obj_cast.h"
 | 
			
		||||
#include "sql/session/ob_sql_session_info.h"
 | 
			
		||||
#include "lib/signal/safe_snprintf.h"
 | 
			
		||||
#include "ob_expr_json_func_helper.h"
 | 
			
		||||
using namespace oceanbase::common;
 | 
			
		||||
using namespace oceanbase::sql;
 | 
			
		||||
@ -168,7 +168,7 @@ int ObExprJsonSearch::find_matches(common::ObIAllocator *allocator,
 | 
			
		||||
            } else {
 | 
			
		||||
              uint64_t reserve_len = i == 0 ? 3 : static_cast<uint64_t>(std::log10(i)) + 3;
 | 
			
		||||
              char temp_buf[reserve_len + 1];
 | 
			
		||||
              int64_t count = safe_snprintf(temp_buf, reserve_len + 1, "[%lu]", i);
 | 
			
		||||
              int64_t count = lnprintf(temp_buf, reserve_len + 1, "[%lu]", i);
 | 
			
		||||
              if (count < 0) {
 | 
			
		||||
                LOG_WARN("fail to snprintf", K(i), K(count));
 | 
			
		||||
              } else if (OB_FAIL(path.append(temp_buf, count))) {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user