mirror of
https://github.com/typesense/typesense.git
synced 2025-05-18 04:32:38 +08:00
Add line numbers to stack trace
This commit is contained in:
parent
ef1306befe
commit
52287b263d
@ -3,8 +3,8 @@ project(typesense)
|
||||
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wno-unused-parameter -O2")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wno-unused-parameter -std=c++11 -O0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wno-unused-parameter -O2 -g")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wno-unused-parameter -std=c++11 -O0 -g")
|
||||
set(DEP_ROOT_DIR ${CMAKE_SOURCE_DIR}/external-${CMAKE_SYSTEM_NAME})
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
|
83
include/stackprinter.h
Normal file
83
include/stackprinter.h
Normal file
@ -0,0 +1,83 @@
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <execinfo.h>
|
||||
#include <regex>
|
||||
|
||||
class StackPrinter {
|
||||
public:
|
||||
|
||||
static std::string getexepath() {
|
||||
char result[PATH_MAX];
|
||||
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
|
||||
return std::string(result, (count > 0) ? count : 0);
|
||||
}
|
||||
|
||||
static std::string sh(const std::string& cmd) {
|
||||
std::array<char, 128> buffer;
|
||||
std::string result;
|
||||
std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
|
||||
if (!pipe) throw std::runtime_error("popen() failed!");
|
||||
|
||||
size_t bt_num = 0;
|
||||
|
||||
std::string optional_space;
|
||||
#if __linux__
|
||||
optional_space = " ";
|
||||
#endif
|
||||
|
||||
while (!feof(pipe.get())) {
|
||||
if (fgets(buffer.data(), 128, pipe.get()) != nullptr) {
|
||||
if(bt_num++ % 2 == 1) {
|
||||
result += optional_space + buffer.data();
|
||||
} else {
|
||||
result += buffer.data();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void bt_sighandler(int sig) {
|
||||
LOG(ERROR) << "Typesense crashed. Generating stack trace...";
|
||||
|
||||
void *bt[1024];
|
||||
int bt_size;
|
||||
char **bt_syms;
|
||||
int i;
|
||||
|
||||
bt_size = backtrace(bt, 1024);
|
||||
bt_syms = backtrace_symbols(bt, bt_size);
|
||||
|
||||
std::regex linux_address_re("\\[(.+)\\]");
|
||||
std::string addrs;
|
||||
|
||||
for (i = 1; i < bt_size; i++) {
|
||||
std::string sym = bt_syms[i];
|
||||
|
||||
#if __linux__
|
||||
std::smatch matches;
|
||||
if (std::regex_search(sym, matches, linux_address_re)) {
|
||||
std::string addr = matches[1];
|
||||
addrs += " " + addr;
|
||||
}
|
||||
#elif __APPLE__
|
||||
std::vector<std::string> sym_parts;
|
||||
StringUtils::split(sym, sym_parts, " ");
|
||||
addrs += " " + (sym_parts.size() > 2 ? sym_parts[2] : "");
|
||||
#else
|
||||
LOG(ERROR) << sym;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __linux__
|
||||
std::string command = std::string("addr2line -e ") + getexepath() + " -f -C " + addrs;
|
||||
LOG(ERROR) << sh(command);
|
||||
#elif __APPLE__
|
||||
std::string command = std::string("atos -p ") + std::to_string(getpid()) + " " + addrs;
|
||||
LOG(ERROR) << sh(command);
|
||||
#endif
|
||||
|
||||
free(bt_syms);
|
||||
exit(1);
|
||||
}
|
||||
};
|
@ -19,6 +19,8 @@
|
||||
#include "threadpool.h"
|
||||
#include "jemalloc.h"
|
||||
|
||||
#include "stackprinter.h"
|
||||
|
||||
HttpServer* server;
|
||||
std::atomic<bool> quit_raft_service;
|
||||
|
||||
@ -43,22 +45,6 @@ void catch_interrupt(int sig) {
|
||||
quit_raft_service = true;
|
||||
}
|
||||
|
||||
void catch_crash(int sig) {
|
||||
void *bt[1024];
|
||||
char **bt_syms;
|
||||
size_t bt_size;
|
||||
|
||||
bt_size = backtrace(bt, 1024);
|
||||
bt_syms = backtrace_symbols(bt, bt_size);
|
||||
|
||||
LOG(ERROR) << "Typesense crashed...";
|
||||
for (size_t i = 0; i < bt_size; i++) {
|
||||
LOG(ERROR) << bt_syms[i];
|
||||
}
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
Option<std::string> fetch_file_contents(const std::string & file_path) {
|
||||
if(!file_exists(file_path)) {
|
||||
return Option<std::string>(404, std::string("File does not exist at: ") + file_path);
|
||||
@ -106,11 +92,10 @@ void init_cmdline_options(cmdline::parser & options, int argc, char **argv) {
|
||||
}
|
||||
|
||||
int init_logger(Config & config, const std::string & server_version) {
|
||||
// remove SIGTERM since we handle it on our own
|
||||
signal(SIGABRT, catch_crash);
|
||||
signal(SIGFPE, catch_crash);
|
||||
signal(SIGILL, catch_crash);
|
||||
signal(SIGSEGV, catch_crash);
|
||||
signal(SIGABRT, StackPrinter::bt_sighandler);
|
||||
signal(SIGFPE, StackPrinter::bt_sighandler);
|
||||
signal(SIGILL, StackPrinter::bt_sighandler);
|
||||
signal(SIGSEGV, StackPrinter::bt_sighandler);
|
||||
|
||||
// we can install new signal handlers only after overriding above
|
||||
signal(SIGINT, catch_interrupt);
|
||||
|
Loading…
x
Reference in New Issue
Block a user