fix(os): add print trace func.
This commit is contained in:
parent
9d2ba0a360
commit
32e6557353
|
@ -0,0 +1,12 @@
|
|||
|
||||
# addr2line
|
||||
ExternalProject_Add(addr2line
|
||||
GIT_REPOSITORY https://github.com/davea42/libdwarf-addr2line.git
|
||||
GIT_TAG master
|
||||
SOURCE_DIR "${TD_CONTRIB_DIR}/addr2line"
|
||||
BINARY_DIR "${TD_CONTRIB_DIR}/addr2line"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
)
|
|
@ -48,6 +48,12 @@ IF(${TD_WINDOWS})
|
|||
|
||||
ENDIF ()
|
||||
|
||||
option(
|
||||
BUILD_ADDR2LINE
|
||||
"If build addr2line"
|
||||
OFF
|
||||
)
|
||||
|
||||
option(
|
||||
BUILD_TEST
|
||||
"If build unit tests using googletest"
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
# libdwarf
|
||||
ExternalProject_Add(libdwarf
|
||||
GIT_REPOSITORY https://github.com/davea42/libdwarf-code.git
|
||||
GIT_TAG libdwarf-0.3.1
|
||||
SOURCE_DIR "${TD_CONTRIB_DIR}/libdwarf"
|
||||
BINARY_DIR "${TD_CONTRIB_DIR}/libdwarf"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
)
|
|
@ -98,6 +98,12 @@ if(${BUILD_WITH_NURAFT})
|
|||
cat("${TD_SUPPORT_DIR}/nuraft_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
endif(${BUILD_WITH_NURAFT})
|
||||
|
||||
# addr2line
|
||||
if(${BUILD_ADDR2LINE})
|
||||
cat("${TD_SUPPORT_DIR}/libdwarf_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
cat("${TD_SUPPORT_DIR}/addr2line_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
endif(${BUILD_ADDR2LINE})
|
||||
|
||||
# download dependencies
|
||||
configure_file(${CONTRIB_TMP_FILE} "${TD_CONTRIB_DIR}/deps-download/CMakeLists.txt")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
||||
|
@ -327,7 +333,48 @@ if(${BUILD_WITH_SQLITE})
|
|||
endif(NOT TD_WINDOWS)
|
||||
endif(${BUILD_WITH_SQLITE})
|
||||
|
||||
# pthread
|
||||
# addr2line
|
||||
if(${BUILD_ADDR2LINE})
|
||||
check_include_file( "sys/types.h" HAVE_SYS_TYPES_H)
|
||||
check_include_file( "sys/stat.h" HAVE_SYS_STAT_H )
|
||||
check_include_file( "inttypes.h" HAVE_INTTYPES_H )
|
||||
check_include_file( "stddef.h" HAVE_STDDEF_H )
|
||||
check_include_file( "stdlib.h" HAVE_STDLIB_H )
|
||||
check_include_file( "string.h" HAVE_STRING_H )
|
||||
check_include_file( "memory.h" HAVE_MEMORY_H )
|
||||
check_include_file( "strings.h" HAVE_STRINGS_H )
|
||||
check_include_file( "stdint.h" HAVE_STDINT_H )
|
||||
check_include_file( "unistd.h" HAVE_UNISTD_H )
|
||||
check_include_file( "sgidefs.h" HAVE_SGIDEFS_H )
|
||||
check_include_file( "stdafx.h" HAVE_STDAFX_H )
|
||||
check_include_file( "elf.h" HAVE_ELF_H )
|
||||
check_include_file( "libelf.h" HAVE_LIBELF_H )
|
||||
check_include_file( "libelf/libelf.h" HAVE_LIBELF_LIBELF_H)
|
||||
check_include_file( "alloca.h" HAVE_ALLOCA_H )
|
||||
check_include_file( "elfaccess.h" HAVE_ELFACCESS_H)
|
||||
check_include_file( "sys/elf_386.h" HAVE_SYS_ELF_386_H )
|
||||
check_include_file( "sys/elf_amd64.h" HAVE_SYS_ELF_AMD64_H)
|
||||
check_include_file( "sys/elf_sparc.h" HAVE_SYS_ELF_SPARC_H)
|
||||
check_include_file( "sys/ia64/elf.h" HAVE_SYS_IA64_ELF_H )
|
||||
set(VERSION 0.3.1)
|
||||
set(PACKAGE_VERSION "\"${VERSION}\"")
|
||||
configure_file(libdwarf/cmake/config.h.cmake config.h)
|
||||
file(GLOB_RECURSE LIBDWARF_SOURCES "libdwarf/src/lib/libdwarf/*.c")
|
||||
add_library(libdwarf STATIC ${LIBDWARF_SOURCES})
|
||||
set_target_properties(libdwarf PROPERTIES OUTPUT_NAME "libdwarf")
|
||||
if(HAVE_LIBELF_H OR HAVE_LIBELF_LIBELF_H)
|
||||
target_link_libraries(libdwarf PUBLIC libelf)
|
||||
endif()
|
||||
target_include_directories(libdwarf SYSTEM PUBLIC "libdwarf/src/lib/libdwarf" ${CMAKE_BINARY_DIR}/contrib)
|
||||
file(READ "addr2line/addr2line.c" ADDR2LINE_CONTENT)
|
||||
string(REPLACE "static int" "int" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
string(REPLACE "static void" "void" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
string(REPLACE "main(" "main_addr2line(" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
file(WRITE "addr2line/addr2line.c" "${ADDR2LINE_CONTENT}")
|
||||
add_library(addr2line STATIC "addr2line/addr2line.c")
|
||||
target_link_libraries(addr2line PUBLIC libdwarf dl z)
|
||||
target_include_directories(addr2line PUBLIC "libdwarf/src/lib/libdwarf" )
|
||||
endif(${BUILD_ADDR2LINE})
|
||||
|
||||
|
||||
# ================================================================================================
|
||||
|
|
|
@ -35,6 +35,7 @@ void *taosMemoryRealloc(void *ptr, int32_t size);
|
|||
void *taosMemoryStrDup(void *ptr);
|
||||
void taosMemoryFree(void *ptr);
|
||||
int32_t taosMemorySize(void *ptr);
|
||||
void taosPrintBackTrace();
|
||||
|
||||
#define taosMemoryFreeClear(ptr) \
|
||||
do { \
|
||||
|
|
|
@ -17,15 +17,25 @@ endif ()
|
|||
if(USE_TD_MEMORY)
|
||||
add_definitions(-DUSE_TD_MEMORY)
|
||||
endif ()
|
||||
if(BUILD_ADDR2LINE)
|
||||
target_include_directories(
|
||||
os
|
||||
PUBLIC "${TD_SOURCE_DIR}/contrib/libdwarf/src/lib/libdwarf"
|
||||
)
|
||||
add_definitions(-DUSE_ADDR2LINE)
|
||||
target_link_libraries(
|
||||
os PUBLIC addr2line dl z
|
||||
)
|
||||
endif ()
|
||||
target_link_libraries(
|
||||
os pthread
|
||||
os PUBLIC pthread
|
||||
)
|
||||
if(NOT TD_WINDOWS)
|
||||
target_link_libraries(
|
||||
os dl m rt
|
||||
os PUBLIC dl m rt
|
||||
)
|
||||
else()
|
||||
target_link_libraries(
|
||||
os ws2_32 iconv msvcregex wcwidth winmm
|
||||
os PUBLIC ws2_32 iconv msvcregex wcwidth winmm
|
||||
)
|
||||
endif(NOT TD_WINDOWS)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <malloc.h>
|
||||
#include "os.h"
|
||||
|
||||
#ifdef USE_TD_MEMORY
|
||||
#if defined(USE_TD_MEMORY) || defined(USE_ADDR2LINE)
|
||||
|
||||
#define TD_MEMORY_SYMBOL ('T' << 24 | 'A' << 16 | 'O' << 8 | 'S')
|
||||
|
||||
|
@ -71,14 +71,110 @@ int32_t taosBackTrace(void **buffer, int32_t size) {
|
|||
return frame;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// char **taosBackTraceSymbols(int32_t *size) {
|
||||
// void *buffer[20] = {NULL};
|
||||
// *size = taosBackTrace(buffer, 20);
|
||||
// return backtrace_symbols(buffer, *size);
|
||||
// }
|
||||
|
||||
#ifdef USE_ADDR2LINE
|
||||
|
||||
#include "osThread.h"
|
||||
#include "libdwarf.h"
|
||||
#include "dwarf.h"
|
||||
|
||||
#define DW_PR_DUu "llu"
|
||||
|
||||
typedef struct lookup_table
|
||||
{
|
||||
Dwarf_Line *table;
|
||||
Dwarf_Line_Context *ctxts;
|
||||
int cnt;
|
||||
Dwarf_Addr low;
|
||||
Dwarf_Addr high;
|
||||
} lookup_tableT;
|
||||
|
||||
extern int create_lookup_table(Dwarf_Debug dbg, lookup_tableT *lookup_table);
|
||||
extern void delete_lookup_table(lookup_tableT *lookup_table);
|
||||
|
||||
size_t addr = 0;
|
||||
lookup_tableT lookup_table;
|
||||
Dwarf_Debug tDbg;
|
||||
static TdThreadOnce traceThreadInit = PTHREAD_ONCE_INIT;
|
||||
|
||||
void endTrace() {
|
||||
delete_lookup_table(&lookup_table);
|
||||
dwarf_finish(tDbg);
|
||||
}
|
||||
void startTrace() {
|
||||
int ret;
|
||||
Dwarf_Ptr errarg = 0;
|
||||
|
||||
FILE *fp = fopen("/proc/self/maps", "r");
|
||||
fscanf(fp, "%lx-", &addr);
|
||||
fclose(fp);
|
||||
|
||||
ret = dwarf_init_path("/proc/self/exe", NULL, 0, DW_GROUPNUMBER_ANY, NULL, errarg, &tDbg, NULL);
|
||||
if (ret == DW_DLV_NO_ENTRY) {
|
||||
printf("Unable to open file");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = create_lookup_table(tDbg, &lookup_table);
|
||||
if (ret != DW_DLV_OK) {
|
||||
printf("Unable to create lookup table");
|
||||
return;
|
||||
}
|
||||
atexit(endTrace);
|
||||
}
|
||||
static void print_line(Dwarf_Debug dbg, Dwarf_Line line, Dwarf_Addr pc) {
|
||||
char *linesrc = "??";
|
||||
Dwarf_Unsigned lineno = 0;
|
||||
|
||||
if (line) {
|
||||
dwarf_linesrc(line, &linesrc, NULL);
|
||||
dwarf_lineno(line, &lineno, NULL);
|
||||
}
|
||||
printf("%s:%" DW_PR_DUu "\n", linesrc, lineno);
|
||||
if (line) dwarf_dealloc(dbg, linesrc, DW_DLA_STRING);
|
||||
}
|
||||
void taosPrintBackTrace() {
|
||||
int size = 20;
|
||||
void **buffer[20];
|
||||
Dwarf_Addr pc;
|
||||
int32_t frame = 0;
|
||||
void **ebp;
|
||||
void **ret = NULL;
|
||||
size_t func_frame_distance = 0;
|
||||
|
||||
taosThreadOnce(&traceThreadInit, startTrace);
|
||||
|
||||
if (buffer != NULL && size > 0) {
|
||||
ebp = taosGetEbp();
|
||||
func_frame_distance = (size_t)*ebp - (size_t)ebp;
|
||||
while (ebp && frame < size && (func_frame_distance < (1ULL << 24)) && (func_frame_distance > 0)) {
|
||||
ret = ebp + 1;
|
||||
buffer[frame++] = *ret;
|
||||
ebp = (void **)(*ebp);
|
||||
func_frame_distance = (size_t)*ebp - (size_t)ebp;
|
||||
}
|
||||
for (size_t i = 0; i < frame; i++) {
|
||||
pc = (size_t)buffer[i] - addr;
|
||||
if (pc > 0) {
|
||||
if (pc >= lookup_table.low && pc < lookup_table.high) {
|
||||
Dwarf_Line line = lookup_table.table[pc - lookup_table.low];
|
||||
if (line) print_line(tDbg, line, pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USE_ADDR2LINE
|
||||
void taosPrintBackTrace() { return; }
|
||||
#endif
|
||||
|
||||
void *taosMemoryMalloc(int32_t size) {
|
||||
|
|
Loading…
Reference in New Issue