[FEAT MERGE] Support PIE
This commit is contained in:
parent
dd74e230e7
commit
42309e3d93
@ -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]);
|
||||
|
6
deps/easy/src/io/easy_log.h
vendored
6
deps/easy/src/io/easy_log.h
vendored
@ -59,10 +59,8 @@ typedef enum {
|
||||
#define easy_trace_log(format, args...) easy_common_log(EASY_LOG_TRACE, format, ## args)
|
||||
#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);}
|
||||
#define EASY_PRINT_BT(format, 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;
|
||||
|
27
deps/easy/src/util/easy_util.c
vendored
27
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;
|
||||
@ -211,7 +195,7 @@ double easy_get_cpu_mhz(int no_cpu_freq_fail)
|
||||
proc = proc_get_cpu_mhz(no_cpu_freq_fail);
|
||||
|
||||
easy_debug_log("Got CPU mhz, sample(%lf), proc(%lf).\n", sample, proc);
|
||||
if ((fabs(proc) < EASY_DOUBLE_EPSINON) ||
|
||||
if ((fabs(proc) < EASY_DOUBLE_EPSINON) ||
|
||||
(fabs(sample) < EASY_DOUBLE_EPSINON)) {
|
||||
return 0;
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
|
@ -158,8 +158,8 @@ inline bool ObMallocSampleKey::operator==(const ObMallocSampleKey &other) const
|
||||
#define ob_malloc_sample_backtrace(obj, size) \
|
||||
{ \
|
||||
if (OB_UNLIKELY(obj->on_malloc_sample_)) { \
|
||||
void *addrs[100]; \
|
||||
int bt_len = backtrace(addrs, ARRAYSIZEOF(addrs)); \
|
||||
void *addrs[100]; \
|
||||
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
|
||||
|
@ -187,7 +187,7 @@ TEST_F(TestJsonPath, test_parse_array_node)
|
||||
ObArenaAllocator allocator(ObModIds::TEST);
|
||||
ObJsonPath test_path1("$[ * ]", &allocator);
|
||||
test_path1.index_ = 1;
|
||||
|
||||
|
||||
ret = test_path1.parse_single_array_node();
|
||||
ASSERT_EQ(1, test_path1.path_node_cnt());
|
||||
ASSERT_EQ(ret, OB_SUCCESS);
|
||||
@ -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;
|
||||
}
|
||||
@ -735,7 +736,7 @@ TEST_F(TestJsonPath, test_parse_path)
|
||||
ASSERT_EQ(true,test_path.path_nodes_[i]->get_node_content().array_range_.is_first_index_from_end_);
|
||||
ASSERT_EQ(1,test_path.path_nodes_[i]->get_node_content().array_range_.last_index_);
|
||||
ASSERT_EQ(true,test_path.path_nodes_[i]->get_node_content().array_range_.is_last_index_from_end_);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -875,27 +876,27 @@ TEST_F(TestJsonPath, test_random)
|
||||
// 添加 JPN_MEMBER_WILDCARD
|
||||
str.append(".*");
|
||||
break;
|
||||
|
||||
|
||||
case 2:
|
||||
// JPN_ARRAY_CELL
|
||||
str.append("[last-5]");
|
||||
break;
|
||||
|
||||
|
||||
case 3:
|
||||
// JPN_ARRAY_RANGE
|
||||
str.append("[10 to last-1]");
|
||||
break;
|
||||
|
||||
|
||||
case 4:
|
||||
// JPN_ARRAY_CELL_WILDCARD
|
||||
str.append("[*]");
|
||||
break;
|
||||
|
||||
|
||||
case 5:
|
||||
// JPN_WILDCARD_ELLIPSIS
|
||||
str.append("**");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -906,7 +907,7 @@ TEST_F(TestJsonPath, test_random)
|
||||
int ret = OB_SUCCESS;
|
||||
ObString str_origin(str.ptr());
|
||||
std::cout<<str_origin.ptr()<<std::endl;
|
||||
|
||||
|
||||
ObJsonPath test_path(str_origin, &allocator);
|
||||
test_path.is_mysql_ = true;
|
||||
if(test_path.is_mysql_ == false){
|
||||
@ -924,7 +925,7 @@ TEST_F(TestJsonPath, test_random)
|
||||
ObString str3(str2.ptr());
|
||||
ASSERT_EQ(str_origin, str3);
|
||||
std::cout<<str2.ptr()<<std::endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// test good path including func_node
|
||||
@ -1343,7 +1344,7 @@ TEST_F(TestJsonPath, test_good_path)
|
||||
ObJsonBuffer str2(&allocator);
|
||||
ret = test_path.to_string(str2);
|
||||
ASSERT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
|
||||
for(int i=0; i<test_path.path_node_cnt(); ++i)
|
||||
{
|
||||
std::cout<<"type:"<<test_path.path_nodes_[i]->get_node_type()<<std::endl;
|
||||
@ -1355,7 +1356,7 @@ TEST_F(TestJsonPath, test_good_path)
|
||||
std::cout<<"content:"<<test_path.path_nodes_[i]->get_node_content().array_cell_.is_index_from_end_<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 验证是否相等 (ObSqlString直接相比会报错,因为没有重载==
|
||||
ObString str3(str2.ptr());
|
||||
std::cout<<str2.ptr()<<std::endl;
|
||||
@ -1367,7 +1368,7 @@ TEST_F(TestJsonPath, test_good_path)
|
||||
TEST_F(TestJsonPath, test_pathcache_funcion) {
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator allocator(ObModIds::TEST);
|
||||
|
||||
|
||||
ObJsonPathCache path_cache(&allocator);
|
||||
ObString ok_path1 = "$.\"abc d\"";
|
||||
|
||||
@ -1405,7 +1406,7 @@ TEST_F(TestJsonPath, test_pathcache_funcion) {
|
||||
TEST_F(TestJsonPath, test_pathcache_exprire) {
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator allocator(ObModIds::TEST);
|
||||
|
||||
|
||||
ObJsonPathCache path_cache(&allocator);
|
||||
ObString ok_path1 = "$.\"abc d\"";
|
||||
|
||||
@ -1434,7 +1435,7 @@ TEST_F(TestJsonPath, test_pathcache_exprire) {
|
||||
TEST_F(TestJsonPath, test_pathcache_reset) {
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator allocator(ObModIds::TEST);
|
||||
|
||||
|
||||
ObJsonPathCache path_cache(&allocator);
|
||||
ObString ok_path1 = "$.\"abc d\"";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user