[FEAT MERGE] Support PIE
This commit is contained in:
		@ -23,7 +23,6 @@ ob_define(OB_CMAKE_RULES_CHECK ON)
 | 
			
		||||
ob_define(OB_STATIC_LINK_LGPL_DEPS ON)
 | 
			
		||||
ob_define(HOTFUNC_PATH "${CMAKE_SOURCE_DIR}/hotfuncs.txt")
 | 
			
		||||
ob_define(OB_BUILD_CCLS OFF)
 | 
			
		||||
ob_define(ENABLE_EXE_PIE OFF)
 | 
			
		||||
 | 
			
		||||
# 'ENABLE_PERF_MODE' use for offline system insight performance test
 | 
			
		||||
# PERF_MODE macro controls many special code path in system
 | 
			
		||||
@ -65,11 +64,6 @@ if(NOT OB_BUILD_CDC)
 | 
			
		||||
  add_definitions(-DENABLE_INITIAL_EXEC_TLS_MODEL)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
ob_define(OB_EXE_LINKER_OPT "")
 | 
			
		||||
if (ENABLE_EXE_PIE)
 | 
			
		||||
  set(OB_EXE_LINKER_OPT "-pie")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(OB_OBJCOPY_BIN "${DEVTOOLS_DIR}/bin/objcopy")
 | 
			
		||||
 | 
			
		||||
# NO RELERO: -Wl,-znorelro
 | 
			
		||||
@ -104,7 +98,7 @@ if (OB_USE_CLANG)
 | 
			
		||||
  set(CMAKE_C_FLAGS "--gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
 | 
			
		||||
  set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} --gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT}")
 | 
			
		||||
  set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT}")
 | 
			
		||||
  set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${OB_EXE_LINKER_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS}")
 | 
			
		||||
  set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack -pie ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS}")
 | 
			
		||||
else() # not clang, use gcc
 | 
			
		||||
  message("gcc9 not support currently, please set OB_USE_CLANG ON and we will finish it as soon as possible")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								deps/easy/src/io/easy_baseth_pool.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/easy/src/io/easy_baseth_pool.c
									
									
									
									
										vendored
									
									
								
							@ -296,7 +296,7 @@ static void easy_baseth_pool_sighand(int sig, siginfo_t *sinfo, void *ucontext)
 | 
			
		||||
        int i, idx = 0;
 | 
			
		||||
        char _buffer_stack_[512];
 | 
			
		||||
 | 
			
		||||
        int n = backtrace(array, 25);
 | 
			
		||||
        int n = ob_backtrace_c(array, 25);
 | 
			
		||||
 | 
			
		||||
        if (n > 2) {
 | 
			
		||||
            for (i = 2; i < n; i++) idx += lnprintf(idx + _buffer_stack_, 20, "%p ", array[i]);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								deps/easy/src/io/easy_log.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/easy/src/io/easy_log.h
									
									
									
									
										vendored
									
									
								
							@ -60,9 +60,7 @@ typedef enum {
 | 
			
		||||
#define SYS_ERROR(format...) easy_error_log(format)
 | 
			
		||||
// 打印backtrace
 | 
			
		||||
#define EASY_PRINT_BT(format, args...) \
 | 
			
		||||
    {char _buffer_stack_[256];{void *array[10];int i, idx=0, n = backtrace(array, 10);        \
 | 
			
		||||
            for (i = 0; i < n; i++) idx += lnprintf(idx+_buffer_stack_, 25, "%p ", array[i]);}\
 | 
			
		||||
        easy_log_format(EASY_LOG_OFF, __FILE__, __LINE__, __FUNCTION__, "%s" format, _buffer_stack_, ## args);}
 | 
			
		||||
  {easy_log_format(EASY_LOG_OFF, __FILE__, __LINE__, __FUNCTION__, "%s" format, easy_lbt(), ## args);}
 | 
			
		||||
 | 
			
		||||
extern easy_log_level_t easy_log_level;
 | 
			
		||||
extern easy_log_format_pt easy_log_format;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								deps/easy/src/util/easy_util.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								deps/easy/src/util/easy_util.c
									
									
									
									
										vendored
									
									
								
							@ -20,29 +20,13 @@
 | 
			
		||||
#define USECSTEP 10
 | 
			
		||||
#define USECSTART 100
 | 
			
		||||
static const double EASY_DOUBLE_EPSINON = 1e-14;
 | 
			
		||||
static char *parray(char *buf, int64_t len, int64_t *array, int size)
 | 
			
		||||
{
 | 
			
		||||
    int64_t pos = 0;
 | 
			
		||||
    int64_t count = 0;
 | 
			
		||||
    int64_t i = 0;
 | 
			
		||||
    for (i = 0; i < size; i++) {
 | 
			
		||||
        count = snprintf(buf + pos, len - pos, "0x%lx ", array[i]);
 | 
			
		||||
        if (count >= 0 && pos + count + 1 < len) {
 | 
			
		||||
            pos += count;
 | 
			
		||||
        } else {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    buf[pos + 1] = 0;
 | 
			
		||||
    return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern char *parray_c(char *buf, int64_t len, int64_t *array, int size);
 | 
			
		||||
const char *easy_lbt()
 | 
			
		||||
{
 | 
			
		||||
    static __thread void *addrs[100];
 | 
			
		||||
    static __thread char buf[1024];
 | 
			
		||||
    int size = backtrace(addrs, 100);
 | 
			
		||||
    return parray(buf, sizeof(buf), (int64_t *)addrs, size);
 | 
			
		||||
    int size = ob_backtrace_c(addrs, 100);
 | 
			
		||||
    return parray_c(buf, sizeof(buf), (int64_t *)addrs, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *easy_lbt_str()
 | 
			
		||||
@ -57,7 +41,7 @@ const char *easy_lbt_str()
 | 
			
		||||
    sprintf(buf, "\n");
 | 
			
		||||
    pos++;
 | 
			
		||||
 | 
			
		||||
    size    = backtrace(addrs, 100);
 | 
			
		||||
    size    = ob_backtrace_c(addrs, 100);
 | 
			
		||||
    symbols = backtrace_symbols(addrs, 100);
 | 
			
		||||
    if (NULL == symbols) {
 | 
			
		||||
        return buf;
 | 
			
		||||
@ -223,4 +207,3 @@ double easy_get_cpu_mhz(int no_cpu_freq_fail)
 | 
			
		||||
    }
 | 
			
		||||
    return proc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								deps/easy/src/util/easy_util.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/easy/src/util/easy_util.h
									
									
									
									
										vendored
									
									
								
							@ -15,6 +15,7 @@
 | 
			
		||||
 | 
			
		||||
#include "easy_define.h"
 | 
			
		||||
 | 
			
		||||
extern int ob_backtrace_c(void **buffer, int size);
 | 
			
		||||
const char* easy_lbt();
 | 
			
		||||
const char* easy_lbt_str();
 | 
			
		||||
const char* easy_get_func_name(void *addr);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								deps/oblib/src/lib/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/oblib/src/lib/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@ -225,6 +225,7 @@ ob_set_subtarget(oblib_lib utility
 | 
			
		||||
  utility/ob_tracepoint.cpp
 | 
			
		||||
  utility/ob_utility.cpp
 | 
			
		||||
  utility/utility.cpp
 | 
			
		||||
  utility/ob_backtrace.cpp
 | 
			
		||||
  utility/ob_proto_trans_util.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								deps/oblib/src/lib/alloc/memory_sanity.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/oblib/src/lib/alloc/memory_sanity.cpp
									
									
									
									
										vendored
									
									
								
							@ -53,7 +53,7 @@ void memory_sanity_abort()
 | 
			
		||||
    abort();
 | 
			
		||||
  }
 | 
			
		||||
  void *addrs[128];
 | 
			
		||||
  int n_addr = backtrace(addrs, sizeof(addrs)/sizeof(addrs[0]));
 | 
			
		||||
  int n_addr = ob_backtrace(addrs, sizeof(addrs)/sizeof(addrs[0]));
 | 
			
		||||
  void *vip_addr = NULL;
 | 
			
		||||
  for (int i = 0; NULL == vip_addr && i < n_addr; i++) {
 | 
			
		||||
    for (int j = 0; NULL == vip_addr && j < sizeof(vips)/sizeof(vips[0]); j++) {
 | 
			
		||||
@ -71,7 +71,7 @@ void memory_sanity_abort()
 | 
			
		||||
  if (vip_addr != NULL) {
 | 
			
		||||
    if (REACH_TIME_INTERVAL(1000 * 1000)) {
 | 
			
		||||
      fprintf(stderr, "[ERROR] sanity check failed, vip_addr: %p, lbt: %s\n",
 | 
			
		||||
              vip_addr, oceanbase::common::lbt(addrs, n_addr));
 | 
			
		||||
              vip_addr, oceanbase::common::parray((int64_t*)addrs, n_addr));
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    char buf[8192];
 | 
			
		||||
@ -103,7 +103,7 @@ void memory_sanity_abort()
 | 
			
		||||
    oceanbase::common::backtrace_symbolize(addrs, n_addr, check_vip);
 | 
			
		||||
    while (pos > 0 && '\n' == buf[pos - 1]) pos--;
 | 
			
		||||
    fprintf(stderr, "[ERROR] sanity check failed, vip_func: %s, lbt: %s\nsymbolize:\n%.*s\n", vip_func,
 | 
			
		||||
            oceanbase::common::lbt(addrs, n_addr), pos, buf);
 | 
			
		||||
            oceanbase::common::parray((int64_t*)addrs, n_addr), pos, buf);
 | 
			
		||||
    if ('\0' == vip_func[0]) {
 | 
			
		||||
      abort();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -159,7 +159,7 @@ inline bool ObMallocSampleKey::operator==(const ObMallocSampleKey &other) const
 | 
			
		||||
  {                                                                                                 \
 | 
			
		||||
    if (OB_UNLIKELY(obj->on_malloc_sample_)) {                                                      \
 | 
			
		||||
      void *addrs[100];                                                                             \
 | 
			
		||||
      int bt_len = backtrace(addrs, ARRAYSIZEOF(addrs));                                            \
 | 
			
		||||
      int bt_len = OB_BACKTRACE_M(addrs, ARRAYSIZEOF(addrs));                                       \
 | 
			
		||||
      MEMCPY(&obj->data_[size], (char*)addrs, AOBJECT_BACKTRACE_SIZE);                              \
 | 
			
		||||
      if (AOBJECT_BACKTRACE_COUNT > bt_len) {                                                       \
 | 
			
		||||
        reinterpret_cast<void*&>(obj->data_[size + bt_len * sizeof(void*)]) = nullptr;              \
 | 
			
		||||
 | 
			
		||||
@ -142,6 +142,7 @@ void  __attribute__((constructor(MALLOC_INIT_PRIORITY))) init_global_memory_pool
 | 
			
		||||
  #ifndef OB_USE_ASAN
 | 
			
		||||
  abort_unless(OB_SUCCESS == install_ob_signal_handler());
 | 
			
		||||
  #endif
 | 
			
		||||
  init_proc_map_info();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t get_virtual_memory_used(int64_t *resident_size)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								deps/oblib/src/lib/signal/ob_libunwind.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/oblib/src/lib/signal/ob_libunwind.c
									
									
									
									
										vendored
									
									
								
							@ -34,6 +34,7 @@ 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,7 +47,8 @@ static int safe_backtrace_(unw_context_t *context, char *buf, int64_t len,
 | 
			
		||||
    ret = -1;
 | 
			
		||||
  } else {
 | 
			
		||||
    for (int i = 0; i < n; i++) {
 | 
			
		||||
      int count = safe_snprintf(buf + *pos, len - *pos, "0x%lx", addrs[i]);
 | 
			
		||||
      int64_t addr = get_rel_offset_c(addrs[i]);
 | 
			
		||||
      int count = safe_snprintf(buf + *pos, len - *pos, "0x%lx", addr);
 | 
			
		||||
      count++; // for space
 | 
			
		||||
      if (count > 0 && *pos + count < len) {
 | 
			
		||||
        *pos += count;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										186
									
								
								deps/oblib/src/lib/utility/ob_backtrace.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								deps/oblib/src/lib/utility/ob_backtrace.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define USING_LOG_PREFIX LIB
 | 
			
		||||
 | 
			
		||||
#include "lib/utility/ob_backtrace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <execinfo.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "lib/utility/ob_defer.h"
 | 
			
		||||
#include "lib/utility/ob_macro_utils.h"
 | 
			
		||||
#include "lib/coro/co_var.h"
 | 
			
		||||
 | 
			
		||||
namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
namespace common
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
int ob_backtrace(void **buffer, int size)
 | 
			
		||||
{
 | 
			
		||||
  int rv = 0;
 | 
			
		||||
  if (OB_LIKELY(g_enable_backtrace)) {
 | 
			
		||||
    rv = backtrace(buffer, size);
 | 
			
		||||
  }
 | 
			
		||||
  return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool read_codesegment_addr_range(int64_t &start_addr, int64_t &end_addr)
 | 
			
		||||
{
 | 
			
		||||
  bool bret = false;
 | 
			
		||||
  char fn[64];
 | 
			
		||||
  snprintf(fn, sizeof(fn), "/proc/%d/maps", getpid());
 | 
			
		||||
  FILE *map_file = fopen(fn, "rt");
 | 
			
		||||
  if (!map_file) return bret;
 | 
			
		||||
  DEFER(fclose(map_file));
 | 
			
		||||
  char buff[1024];
 | 
			
		||||
  while (fgets(buff, sizeof buff, map_file) != NULL) {
 | 
			
		||||
    int len = strlen(buff);
 | 
			
		||||
    if (len > 0 && buff[len-1] == '\n') {
 | 
			
		||||
      buff[--len] = '\0';
 | 
			
		||||
    }
 | 
			
		||||
    char* tokens[8];
 | 
			
		||||
    int n_token = 0;
 | 
			
		||||
    for (char *saveptr = NULL, *value = strtok_r(buff, " ", &saveptr);
 | 
			
		||||
         NULL != value && n_token < ARRAYSIZEOF(tokens);
 | 
			
		||||
         value = strtok_r(NULL, " ", &saveptr)) {
 | 
			
		||||
      tokens[n_token++] = value;
 | 
			
		||||
    }
 | 
			
		||||
    if (n_token < 6) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    char *perms = tokens[1];
 | 
			
		||||
    if (strlen(perms) == 4 && perms[2] != 'x') {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    int64_t a0 = 0, a1 = 0;
 | 
			
		||||
    sscanf(tokens[0], "%lx-%lx", &a0, &a1);
 | 
			
		||||
    char *path = tokens[5];
 | 
			
		||||
    if (path[0] == '[') {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    int64_t addr = (int64_t)__func__;
 | 
			
		||||
    if (addr >= a0 && addr < a1) {
 | 
			
		||||
      start_addr = a0;
 | 
			
		||||
      end_addr = a1;
 | 
			
		||||
      bret = true;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return bret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool g_enable_backtrace = true;
 | 
			
		||||
bool g_use_rel_offset = false;
 | 
			
		||||
struct ProcMapInfo
 | 
			
		||||
{
 | 
			
		||||
  int64_t code_start_addr_;
 | 
			
		||||
  int64_t code_end_addr_;
 | 
			
		||||
  bool is_inited_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ProcMapInfo g_proc_map_info{.code_start_addr_ = -1, .code_end_addr_ = -1, .is_inited_ = false};
 | 
			
		||||
 | 
			
		||||
void init_proc_map_info()
 | 
			
		||||
{
 | 
			
		||||
  read_codesegment_addr_range(g_proc_map_info.code_start_addr_, g_proc_map_info.code_end_addr_);
 | 
			
		||||
  g_proc_map_info.is_inited_ = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t get_rel_offset(int64_t addr)
 | 
			
		||||
{
 | 
			
		||||
  if (g_use_rel_offset) {
 | 
			
		||||
    int64_t code_start_addr = -1;
 | 
			
		||||
    int64_t code_end_addr = -1;
 | 
			
		||||
    if (OB_UNLIKELY(!g_proc_map_info.is_inited_)) {
 | 
			
		||||
      read_codesegment_addr_range(code_start_addr, code_end_addr);
 | 
			
		||||
    } else {
 | 
			
		||||
      code_start_addr = g_proc_map_info.code_start_addr_;
 | 
			
		||||
      code_end_addr = g_proc_map_info.code_end_addr_;
 | 
			
		||||
    }
 | 
			
		||||
    if (code_start_addr != -1) {
 | 
			
		||||
      if (OB_LIKELY(addr >= code_start_addr && addr < code_end_addr)) {
 | 
			
		||||
        addr -= code_start_addr;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
constexpr int MAX_ADDRS_COUNT = 100;
 | 
			
		||||
using PointerBuf = void *[MAX_ADDRS_COUNT];
 | 
			
		||||
RLOCAL(PointerBuf, addrs);
 | 
			
		||||
RLOCAL(ByteBuf<LBT_BUFFER_LENGTH>, buffer);
 | 
			
		||||
 | 
			
		||||
char *lbt()
 | 
			
		||||
{
 | 
			
		||||
  int size = OB_BACKTRACE_M(addrs, MAX_ADDRS_COUNT);
 | 
			
		||||
  return parray(*&buffer, LBT_BUFFER_LENGTH, (int64_t *)addrs, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *lbt(char *buf, int32_t len)
 | 
			
		||||
{
 | 
			
		||||
  int size = OB_BACKTRACE_M(addrs, MAX_ADDRS_COUNT);
 | 
			
		||||
  return parray(buf, len, (int64_t *)addrs, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *parray(int64_t *array, int size)
 | 
			
		||||
{
 | 
			
		||||
  return parray(buffer, LBT_BUFFER_LENGTH, array, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *parray(char *buf, int64_t len, int64_t *array, int size)
 | 
			
		||||
{
 | 
			
		||||
  //As used in lbt, and lbt used when print error log.
 | 
			
		||||
  //Can not print error log this function.
 | 
			
		||||
  if (NULL != buf && len > 0 && NULL != array) {
 | 
			
		||||
    int64_t pos = 0;
 | 
			
		||||
    int64_t count = 0;
 | 
			
		||||
    for (int64_t i = 0; i < size; i++) {
 | 
			
		||||
      int64_t addr = get_rel_offset(array[i]);
 | 
			
		||||
      if (0 == i) {
 | 
			
		||||
        count = snprintf(buf + pos, len - pos, "0x%lx", addr);
 | 
			
		||||
      } else {
 | 
			
		||||
        count = snprintf(buf + pos, len - pos, " 0x%lx", addr);
 | 
			
		||||
      }
 | 
			
		||||
      if (count >= 0 && pos + count < len) {
 | 
			
		||||
        pos += count;
 | 
			
		||||
      } else {
 | 
			
		||||
        // buf not enough
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    buf[pos] = 0;
 | 
			
		||||
  }
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXTERN_C_BEGIN
 | 
			
		||||
int ob_backtrace_c(void **buffer, int size)
 | 
			
		||||
{
 | 
			
		||||
  return OB_BACKTRACE_M(buffer, size);
 | 
			
		||||
}
 | 
			
		||||
char *parray_c(char *buf, int64_t len, int64_t *array, int size)
 | 
			
		||||
{
 | 
			
		||||
  return parray(buf, len, array, size);
 | 
			
		||||
}
 | 
			
		||||
int64_t get_rel_offset_c(int64_t addr)
 | 
			
		||||
{
 | 
			
		||||
  return get_rel_offset(addr);
 | 
			
		||||
}
 | 
			
		||||
EXTERN_C_END
 | 
			
		||||
 | 
			
		||||
} // end namespace common
 | 
			
		||||
} // end namespace oceanbase
 | 
			
		||||
							
								
								
									
										42
									
								
								deps/oblib/src/lib/utility/ob_backtrace.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								deps/oblib/src/lib/utility/ob_backtrace.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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_COMMON_OB_BACKTRACE_H_
 | 
			
		||||
#define OCEANBASE_COMMON_OB_BACKTRACE_H_
 | 
			
		||||
 | 
			
		||||
#include<inttypes.h>
 | 
			
		||||
namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
namespace common
 | 
			
		||||
{
 | 
			
		||||
void init_proc_map_info();
 | 
			
		||||
extern bool g_enable_backtrace;
 | 
			
		||||
extern bool g_use_rel_offset;
 | 
			
		||||
const int64_t LBT_BUFFER_LENGTH = 1024;
 | 
			
		||||
int ob_backtrace(void **buffer, int size);
 | 
			
		||||
// save one layer of call stack
 | 
			
		||||
#define OB_BACKTRACE_M(buffer, size)                      \
 | 
			
		||||
  ({                                                      \
 | 
			
		||||
    int rv = 0;                                           \
 | 
			
		||||
    if (OB_LIKELY(::oceanbase::common::g_enable_backtrace)) {   \
 | 
			
		||||
      rv = backtrace(buffer, size);                       \
 | 
			
		||||
    }                                                     \
 | 
			
		||||
  rv;                                                     \
 | 
			
		||||
  })
 | 
			
		||||
char *lbt();
 | 
			
		||||
char *lbt(char *buf, int32_t len);
 | 
			
		||||
char *parray(int64_t *array, int size);
 | 
			
		||||
char *parray(char *buf, int64_t len, int64_t *array, int size);
 | 
			
		||||
} // end namespace common
 | 
			
		||||
} // end namespace oceanbase
 | 
			
		||||
 | 
			
		||||
#endif //OCEANBASE_COMMON_OB_BACKTRACE_H_
 | 
			
		||||
							
								
								
									
										2
									
								
								deps/oblib/src/lib/utility/ob_preload.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/oblib/src/lib/utility/ob_preload.h
									
									
									
									
										vendored
									
									
								
							@ -26,7 +26,7 @@ inline int64_t &bt(const char *msg)
 | 
			
		||||
  static int64_t enable_bt = 0;
 | 
			
		||||
  if (enable_bt > 0) {
 | 
			
		||||
    void *buffer[100];
 | 
			
		||||
    int size = backtrace(buffer, 100);
 | 
			
		||||
    int size = ob_backtrace(buffer, 100);
 | 
			
		||||
    char **strings = backtrace_symbols(buffer, size);
 | 
			
		||||
    _OB_LOG(DEBUG, "%s", msg);
 | 
			
		||||
    if (NULL != strings) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										47
									
								
								deps/oblib/src/lib/utility/utility.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								deps/oblib/src/lib/utility/utility.cpp
									
									
									
									
										vendored
									
									
								
							@ -13,6 +13,7 @@
 | 
			
		||||
#define USING_LOG_PREFIX LIB
 | 
			
		||||
 | 
			
		||||
#include "dirent.h"
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include "lib/utility/utility.h"
 | 
			
		||||
#include "lib/ob_define.h"
 | 
			
		||||
#include "util/easy_inet.h"
 | 
			
		||||
@ -37,52 +38,6 @@ extern "C"
 | 
			
		||||
  void do_breakpad_init()
 | 
			
		||||
  {}
 | 
			
		||||
}
 | 
			
		||||
char *parray(char *buf, int64_t len, int64_t *array, int size)
 | 
			
		||||
{
 | 
			
		||||
  //As used in lbt, and lbt used when print error log.
 | 
			
		||||
  //Can not print error log this function.
 | 
			
		||||
  if (NULL != buf && len > 0 && NULL != array) {
 | 
			
		||||
    int64_t pos = 0;
 | 
			
		||||
    int64_t count = 0;
 | 
			
		||||
    for (int64_t i = 0; i < size; i++) {
 | 
			
		||||
      if (0 == i) {
 | 
			
		||||
        count = snprintf(buf + pos, len - pos, "0x%lx", array[i]);
 | 
			
		||||
      } else {
 | 
			
		||||
        count = snprintf(buf + pos, len - pos, " 0x%lx", array[i]);
 | 
			
		||||
      }
 | 
			
		||||
      if (count >= 0 && pos + count < len) {
 | 
			
		||||
        pos += count;
 | 
			
		||||
      } else {
 | 
			
		||||
        // buf not enough
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    buf[pos] = 0;
 | 
			
		||||
  }
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr int MAX_ADDRS_COUNT = 100;
 | 
			
		||||
using PointerBuf = void *[MAX_ADDRS_COUNT];
 | 
			
		||||
RLOCAL(PointerBuf, addrs);
 | 
			
		||||
RLOCAL(ByteBuf<LBT_BUFFER_LENGTH>, buffer);
 | 
			
		||||
 | 
			
		||||
char *lbt()
 | 
			
		||||
{
 | 
			
		||||
  int size = backtrace(addrs, MAX_ADDRS_COUNT);
 | 
			
		||||
  return parray(*&buffer, LBT_BUFFER_LENGTH, (int64_t *)*&addrs, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *lbt(char *buf, int32_t len)
 | 
			
		||||
{
 | 
			
		||||
  int size = backtrace(addrs, MAX_ADDRS_COUNT);
 | 
			
		||||
  return parray(buf, len, (int64_t *)*&addrs, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *lbt(void **addrs, int32_t size)
 | 
			
		||||
{
 | 
			
		||||
  return parray(*&buffer, LBT_BUFFER_LENGTH, (int64_t *)*&addrs, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hex_dump(const void *data, const int32_t size,
 | 
			
		||||
              const bool char_type /*= true*/, const int32_t log_level /*= OB_LOG_LEVEL_DEBUG*/)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								deps/oblib/src/lib/utility/utility.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/oblib/src/lib/utility/utility.h
									
									
									
									
										vendored
									
									
								
							@ -22,6 +22,7 @@
 | 
			
		||||
#include "lib/stat/ob_diagnose_info.h"
 | 
			
		||||
#include "lib/utility/ob_print_utils.h"
 | 
			
		||||
#include "lib/utility/ob_utility.h"
 | 
			
		||||
#include "lib/utility/ob_backtrace.h"
 | 
			
		||||
#include "lib/oblog/ob_trace_log.h"
 | 
			
		||||
#include "lib/container/ob_iarray.h"
 | 
			
		||||
 | 
			
		||||
@ -63,11 +64,6 @@ struct ObObj;
 | 
			
		||||
class ObObjParam;
 | 
			
		||||
class ObAddr;
 | 
			
		||||
 | 
			
		||||
const int64_t LBT_BUFFER_LENGTH = 1024;
 | 
			
		||||
char *parray(char *buf, int64_t len, int64_t *array, int size);
 | 
			
		||||
char *lbt();
 | 
			
		||||
char *lbt(char *buf, int32_t len);
 | 
			
		||||
char *lbt(void **addrs, int32_t size);
 | 
			
		||||
void hex_dump(const void *data, const int32_t size,
 | 
			
		||||
              const bool char_type = true, const int32_t log_level = OB_LOG_LEVEL_DEBUG);
 | 
			
		||||
int32_t parse_string_to_int_array(const char *line,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								deps/oblib/src/rpc/frame/ob_net_easy.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								deps/oblib/src/rpc/frame/ob_net_easy.cpp
									
									
									
									
										vendored
									
									
								
							@ -579,6 +579,14 @@ int ObNetEasy::load_ssl_config(const bool use_bkmi,
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void do_not_optimize(T const& value)
 | 
			
		||||
{
 | 
			
		||||
  asm volatile("" : : "g"(value) : "memory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If there is a hang problem in the lbt,
 | 
			
		||||
// you can use the disaster recovery capability of the observer to switch traffic
 | 
			
		||||
static void rpc_easy_timer_cb(EV_P_ ev_timer *w, int revents)
 | 
			
		||||
{
 | 
			
		||||
  UNUSED(loop);
 | 
			
		||||
@ -636,6 +644,17 @@ static void batch_rpc_easy_timer_cb(EV_P_ ev_timer *w, int revents)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define DEFINE_CB_WITH_LBT(cb)                             \
 | 
			
		||||
static void cb##_with_lbt(EV_P_ ev_timer *w, int revents)  \
 | 
			
		||||
{                                                          \
 | 
			
		||||
  do_not_optimize(lbt());                                  \
 | 
			
		||||
  cb(loop, w, revents);                                    \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEFINE_CB_WITH_LBT(rpc_easy_timer_cb)
 | 
			
		||||
DEFINE_CB_WITH_LBT(high_prio_rpc_easy_timer_cb)
 | 
			
		||||
DEFINE_CB_WITH_LBT(batch_rpc_easy_timer_cb)
 | 
			
		||||
 | 
			
		||||
static void mysql_easy_timer_cb(EV_P_ ev_timer *w, int revents)
 | 
			
		||||
{
 | 
			
		||||
  UNUSED(loop);
 | 
			
		||||
@ -710,7 +729,7 @@ int ObNetEasy::init(const ObNetOptions &opts, uint8_t negotiation_enable)
 | 
			
		||||
      {
 | 
			
		||||
        if (!OB_ISNULL(ioth)) {
 | 
			
		||||
          ev_timer_init(&ioth->user_timer,
 | 
			
		||||
                        rpc_easy_timer_cb, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
                        rpc_easy_timer_cb_with_lbt, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
          ev_timer_start(ioth->loop, &(ioth->user_timer));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@ -721,7 +740,7 @@ int ObNetEasy::init(const ObNetOptions &opts, uint8_t negotiation_enable)
 | 
			
		||||
        {
 | 
			
		||||
          if (!OB_ISNULL(ioth)) {
 | 
			
		||||
            ev_timer_init(&ioth->user_timer,
 | 
			
		||||
                          high_prio_rpc_easy_timer_cb, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
                          high_prio_rpc_easy_timer_cb_with_lbt, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
            ev_timer_start(ioth->loop, &(ioth->user_timer));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
@ -732,7 +751,7 @@ int ObNetEasy::init(const ObNetOptions &opts, uint8_t negotiation_enable)
 | 
			
		||||
      {
 | 
			
		||||
        if (!OB_ISNULL(ioth)) {
 | 
			
		||||
          ev_timer_init(&ioth->user_timer,
 | 
			
		||||
                        batch_rpc_easy_timer_cb, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
                        batch_rpc_easy_timer_cb_with_lbt, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
          ev_timer_start(ioth->loop, &(ioth->user_timer));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@ -766,7 +785,7 @@ int ObNetEasy::init(const ObNetOptions &opts, uint8_t negotiation_enable)
 | 
			
		||||
        {
 | 
			
		||||
          if (!OB_ISNULL(ioth)) {
 | 
			
		||||
            ev_timer_init(&ioth->user_timer,
 | 
			
		||||
                        rpc_easy_timer_cb, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
                        rpc_easy_timer_cb_with_lbt, EASY_STAT_INTERVAL, EASY_STAT_INTERVAL);
 | 
			
		||||
            ev_timer_start(ioth->loop, &(ioth->user_timer));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1310,7 +1310,7 @@ char *lbt_oblog()
 | 
			
		||||
  //in this function and functions called.
 | 
			
		||||
  static __thread void *addrs[100];
 | 
			
		||||
  static __thread char buf[LBT_BUFFER_LENGTH];
 | 
			
		||||
  int size = backtrace(addrs, 100);
 | 
			
		||||
  int size = ob_backtrace(addrs, 100);
 | 
			
		||||
  char **res = backtrace_symbols(addrs, 100);
 | 
			
		||||
  int64_t pos = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -406,6 +406,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
    snprintf(ob_get_tname(), OB_THREAD_NAME_BUF_LEN, "observer");
 | 
			
		||||
  }
 | 
			
		||||
  ObStackHeaderGuard stack_header_guard;
 | 
			
		||||
  g_use_rel_offset = true;
 | 
			
		||||
#ifndef OB_USE_ASAN
 | 
			
		||||
  init_malloc_hook();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -201,7 +201,7 @@ int ObInnerSQLConnection::init(ObInnerSQLConnectionPool *pool,
 | 
			
		||||
    tid_ = GETTID();
 | 
			
		||||
    if (NULL == extern_session || 0 != EVENT_CALL(EventTable::EN_INNER_SQL_CONN_LEAK_CHECK)) {
 | 
			
		||||
      // Only backtrace internal used connection to avoid performance problems.
 | 
			
		||||
      bt_size_ = backtrace(bt_addrs_, MAX_BT_SIZE);
 | 
			
		||||
      bt_size_ = ob_backtrace(bt_addrs_, MAX_BT_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
    config_ = config;
 | 
			
		||||
    associated_client_ = client_addr;
 | 
			
		||||
@ -2317,13 +2317,7 @@ void ObInnerSQLConnection::dump_conn_bt_info()
 | 
			
		||||
  int64_t pos = 0;
 | 
			
		||||
  (void)ObTimeUtility2::usec_to_str(init_timestamp_, buf_time, OB_MAX_TIMESTAMP_LENGTH, pos);
 | 
			
		||||
  pos = 0;
 | 
			
		||||
  for (int i = 0; i < bt_size_; ++i) {
 | 
			
		||||
    if (OB_UNLIKELY(pos + 1 > BUF_SIZE)) {
 | 
			
		||||
      LOG_WARN_RET(OB_ERR_UNEXPECTED, "buf is not large enough", K(pos), K(BUF_SIZE));
 | 
			
		||||
    } else {
 | 
			
		||||
      (void)databuff_printf(buf_bt, BUF_SIZE, pos, "%p ", bt_addrs_[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  parray(buf_bt, BUF_SIZE, (int64_t*)*&bt_addrs_, bt_size_);
 | 
			
		||||
  LOG_WARN_RET(OB_SUCCESS, "dump inner sql connection backtrace", "tid", tid_, "init time", buf_time, "backtrace", buf_bt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -298,6 +298,10 @@ int ObServerReloadConfig::operator()()
 | 
			
		||||
  {
 | 
			
		||||
    ObSysVariables::set_value("datadir", GCONF.data_dir);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    common::g_enable_backtrace = GCONF._enable_backtrace_function;
 | 
			
		||||
  }
 | 
			
		||||
  return real_ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1416,3 +1416,6 @@ DEF_INT(_pipelined_table_function_memory_limit, OB_TENANT_PARAMETER, "524288000"
 | 
			
		||||
DEF_BOOL(_enable_reserved_user_dcl_restriction, OB_CLUSTER_PARAMETER, "False",
 | 
			
		||||
         "specifies whether to forbid non-reserved user to modify reserved users",
 | 
			
		||||
         ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
 | 
			
		||||
DEF_BOOL(_enable_backtrace_function, OB_CLUSTER_PARAMETER, "True",
 | 
			
		||||
         "Decide whether to let the backtrace function take effect",
 | 
			
		||||
         ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
 | 
			
		||||
 | 
			
		||||
@ -244,6 +244,7 @@ _chunk_row_store_mem_limit
 | 
			
		||||
_ctx_memory_limit
 | 
			
		||||
_data_storage_io_timeout
 | 
			
		||||
_enable_adaptive_compaction
 | 
			
		||||
_enable_backtrace_function
 | 
			
		||||
_enable_block_file_punch_hole
 | 
			
		||||
_enable_compaction_diagnose
 | 
			
		||||
_enable_convert_real_to_decimal
 | 
			
		||||
 | 
			
		||||
@ -683,7 +683,8 @@ TEST_F(TestJsonPath, test_member_node)
 | 
			
		||||
  // 只有一个节点
 | 
			
		||||
  ASSERT_EQ(1, test_path.path_node_cnt());
 | 
			
		||||
  ASSERT_EQ(JPN_MEMBER,test_path.path_nodes_[0]->get_node_type());
 | 
			
		||||
  ObString str(test_path.path_nodes_[0]->get_node_content().member_.object_name_);
 | 
			
		||||
  const auto &member = test_path.path_nodes_[0]->get_node_content().member_;
 | 
			
		||||
  ObString str(member.len_, member.object_name_);
 | 
			
		||||
  ASSERT_TRUE(str.case_compare("name") == 0);
 | 
			
		||||
  std::cout<<test_path.path_nodes_[0]->get_node_content().member_.object_name_<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user