From 3f10ee020d38bc58579d3c826aded39335c335f1 Mon Sep 17 00:00:00 2001 From: lucas Date: Sat, 9 Jul 2022 11:30:16 +0800 Subject: [PATCH 1/5] feat(base) : add support for call-stack dump --- base/Makefile | 2 + base/backtrace.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++ base/backtrace.h | 64 ++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 base/backtrace.cpp create mode 100644 base/backtrace.h diff --git a/base/Makefile b/base/Makefile index 5b2264a..495d450 100644 --- a/base/Makefile +++ b/base/Makefile @@ -16,10 +16,12 @@ HEAD_FILES = \ memblock.h \ json_fwd.h \ json.hpp \ + backtrace.h CPP_SRC_FILES = \ log_imp.cpp \ log_output.cpp \ + backtrace.cpp CXXFLAGS := -DLOG_MODULE_ID='"tbox_base"' $(CXXFLAGS) diff --git a/base/backtrace.cpp b/base/backtrace.cpp new file mode 100644 index 0000000..ce61370 --- /dev/null +++ b/base/backtrace.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include "backtrace.h" + +static uint32_t g_max_frames = 32; +static uint32_t g_skip_frames = 1; + +Backtrace::Backtrace() +{ } + +Backtrace::~Backtrace() {} + +Backtrace& Backtrace::instance() +{ + static Backtrace ins; + return ins; +} + +void Backtrace::submit() +{ + for (const auto &it : signal_list_) + signal(it.signal_number, it.handler); + + std::vector tmp; + std::swap(tmp, signal_list_); + + /// catch segment fault action + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = Backtrace::handleSigsegv; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, nullptr); +} + +Backtrace& Backtrace::capture(int signo, signal_handler_t handler) +{ + signal_list_.push_back(SignalNode(signo, handler)); + return *this; +} + +Backtrace& Backtrace::maxFrames(unsigned int max_frames) +{ + g_max_frames = max_frames; + return *this; +} + +Backtrace& Backtrace::skip(unsigned int skip) +{ + g_skip_frames = skip; + return *this; +} + +void Backtrace::handleSigsegv(int signal_number, siginfo_t *signal_info, void *arg) +{ + (void) signal_number; + (void) signal_info; + (void) arg; + + std::cerr << "call-stack dumped:" << std::endl; + std::string dumpinfo = Backtrace::backtraceString(g_max_frames, g_skip_frames); + std::cerr << dumpinfo << std::endl; + _exit(signal_number); +} + + +std::string Backtrace::backtraceString(const int max_frames, const int skip) +{ + void *callstack[max_frames]; + char buf[1024] = { 0 }; + std::ostringstream oss; + + int number_frames = ::backtrace(callstack, max_frames); + char **symbols = ::backtrace_symbols(callstack, number_frames); + + for (int i = skip; i < number_frames; ++i) { + Dl_info info; + /// try to translate an address to symbolic information + if (dladdr(callstack[i], &info)) { + char *demangled = nullptr; + int status = -1; + demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); + snprintf(buf, sizeof(buf), BACKTRACE_FORMAT, i, callstack[i], status == 0 ? demangled : info.dli_sname); + if (demangled) free(demangled); + } else + snprintf(buf, sizeof(buf), BACKTRACE_FORMAT, i, callstack[i], symbols[i]); + + oss << buf; + } + + if (symbols) + free(symbols); + + if (number_frames >= max_frames) + oss << "[truncated]\n"; + + return oss.str(); +} diff --git a/base/backtrace.h b/base/backtrace.h new file mode 100644 index 0000000..3320e03 --- /dev/null +++ b/base/backtrace.h @@ -0,0 +1,64 @@ +#ifndef _BACKTRACE_H +#define _BACKTRACE_H + +#include +#include +#include + +#define BACKTRACE_FORMAT "%-2d: %p\t%s\n" // callstack number | address | symbols + +typedef void(*signal_handler_t)(int); + +/* + * @brief - Aims to capture signals and formart human-readable backtrace info if + * recved SIGSEGV signal + * @note - You should add -ldl and -rdynamic to your link parameters + * + * # Examples: + * + * Backtrace::instance() + * .maxFrames(24) // if not set, default is 32 + * .skip(2) // if not set, default is 1 + * .capture(SIGTERM, handle_term) + * .capture(SIGABRT, handle_abort) + * .capture(SIGINT, handle_interrupt) + * .submit(); + */ +class Backtrace +{ +private: + Backtrace(); + ~Backtrace(); + +public: + static Backtrace& instance(); + +public: + Backtrace& capture(int signal_no, signal_handler_t handler); + Backtrace& maxFrames(unsigned int max_frames); // default is 32 + Backtrace& skip(unsigned int skip); // default is 1(will note skip) + + void submit(); + +private: + static void handleSigsegv(int signal_number, siginfo_t *signal_info, void *arg); + + /* + * @brief Generate a human-readable backtrace string + * + * @return backtrace string + */ + static std::string backtraceString(const int max_frames = 32, const int skip = 1); + +private: + struct SignalNode + { + SignalNode(int s,signal_handler_t h) : signal_number(s), handler(h) { } + int signal_number; + signal_handler_t handler; + }; + + std::vector signal_list_; +}; + +#endif // _BACKTRACE_H -- Gitee From 6c70616203953449326617186c1defbcc1206da3 Mon Sep 17 00:00:00 2001 From: Hevake Date: Sat, 9 Jul 2022 17:40:39 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BC=98=E5=8C=96Backtrace=E3=80=82?= =?UTF-8?q?=E5=B0=86backtrace=E6=A8=A1=E5=9D=97=E4=BB=8Ebase=E7=A7=BB?= =?UTF-8?q?=E5=88=B0util=EF=BC=9B=E4=BF=AE=E6=94=B9main=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E7=94=A8util=E4=B8=AD=E7=9A=84backstrace?= =?UTF-8?q?=E6=9B=BF=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base/Makefile | 2 - .../04_initiate_runtime_error/.gitignore | 1 + .../04_initiate_runtime_error/Makefile | 32 ++++++++ .../04_initiate_runtime_error/README.txt | 1 + .../example/04_initiate_runtime_error/app.cpp | 36 +++++++++ main/example/04_initiate_runtime_error/app.h | 18 +++++ .../04_initiate_runtime_error/main.cpp | 31 +++++++ main/signal.cpp | 19 +---- sample/Makefile | 3 +- util/Makefile | 2 + {base => util}/backtrace.cpp | 80 +++++++++---------- {base => util}/backtrace.h | 48 ++++------- util/example/backtrace/.gitignore | 1 + util/example/backtrace/Makefile | 18 +++++ util/example/backtrace/sample.cpp | 22 +++++ util/example/build_env.mk | 29 +++++++ 16 files changed, 249 insertions(+), 94 deletions(-) create mode 100644 main/example/04_initiate_runtime_error/.gitignore create mode 100644 main/example/04_initiate_runtime_error/Makefile create mode 100644 main/example/04_initiate_runtime_error/README.txt create mode 100644 main/example/04_initiate_runtime_error/app.cpp create mode 100644 main/example/04_initiate_runtime_error/app.h create mode 100644 main/example/04_initiate_runtime_error/main.cpp rename {base => util}/backtrace.cpp (36%) rename {base => util}/backtrace.h (43%) create mode 100644 util/example/backtrace/.gitignore create mode 100644 util/example/backtrace/Makefile create mode 100644 util/example/backtrace/sample.cpp create mode 100644 util/example/build_env.mk diff --git a/base/Makefile b/base/Makefile index 495d450..5b2264a 100644 --- a/base/Makefile +++ b/base/Makefile @@ -16,12 +16,10 @@ HEAD_FILES = \ memblock.h \ json_fwd.h \ json.hpp \ - backtrace.h CPP_SRC_FILES = \ log_imp.cpp \ log_output.cpp \ - backtrace.cpp CXXFLAGS := -DLOG_MODULE_ID='"tbox_base"' $(CXXFLAGS) diff --git a/main/example/04_initiate_runtime_error/.gitignore b/main/example/04_initiate_runtime_error/.gitignore new file mode 100644 index 0000000..ae6321f --- /dev/null +++ b/main/example/04_initiate_runtime_error/.gitignore @@ -0,0 +1 @@ +/sample diff --git a/main/example/04_initiate_runtime_error/Makefile b/main/example/04_initiate_runtime_error/Makefile new file mode 100644 index 0000000..d5d8065 --- /dev/null +++ b/main/example/04_initiate_runtime_error/Makefile @@ -0,0 +1,32 @@ +include ../build_env.mk + +.PHONY : all clean distclean + +TARGET := sample +CXXFLAGS += -ggdb -DLOG_MODULE_ID='"demo"' +LDFLAGS += -L.. \ + -ltbox_main \ + -ltbox_log \ + -ltbox_terminal \ + -ltbox_network \ + -ltbox_eventx \ + -ltbox_event \ + -ltbox_util \ + -ltbox_base \ + -lpthread \ + -rdynamic \ + +CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer +LDFLAGS += -fsanitize=address -static-libasan +OBJECTS := main.o app.o + +all : $(TARGET) + +$(TARGET): $(OBJECTS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) + +clean: + rm -rf $(OBJECTS) + +distclean: clean + rm -rf $(TARGET) diff --git a/main/example/04_initiate_runtime_error/README.txt b/main/example/04_initiate_runtime_error/README.txt new file mode 100644 index 0000000..2df846f --- /dev/null +++ b/main/example/04_initiate_runtime_error/README.txt @@ -0,0 +1 @@ +本示例模拟程序出现异常,使程序打印调用栈 diff --git a/main/example/04_initiate_runtime_error/app.cpp b/main/example/04_initiate_runtime_error/app.cpp new file mode 100644 index 0000000..a2d2738 --- /dev/null +++ b/main/example/04_initiate_runtime_error/app.cpp @@ -0,0 +1,36 @@ +#include "app.h" +#include + +App::App(tbox::main::Context &ctx) : + Module("app", ctx) +{ + LogTag(); +} + +App::~App() +{ + LogTag(); +} + +bool App::onInit(const tbox::Json &cfg) +{ + LogTag(); + static_cast(nullptr)[0] = 0; + return true; +} + +bool App::onStart() +{ + LogTag(); + return true; +} + +void App::onStop() +{ + LogTag(); +} + +void App::onCleanup() +{ + LogTag(); +} diff --git a/main/example/04_initiate_runtime_error/app.h b/main/example/04_initiate_runtime_error/app.h new file mode 100644 index 0000000..0da3c56 --- /dev/null +++ b/main/example/04_initiate_runtime_error/app.h @@ -0,0 +1,18 @@ +#ifndef TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 +#define TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 + +#include + +class App : public tbox::main::Module +{ + public: + App(tbox::main::Context &ctx); + ~App(); + protected: + virtual bool onInit(const tbox::Json &cfg) override; + virtual bool onStart() override; + virtual void onStop() override; + virtual void onCleanup() override; +}; + +#endif //TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 diff --git a/main/example/04_initiate_runtime_error/main.cpp b/main/example/04_initiate_runtime_error/main.cpp new file mode 100644 index 0000000..799cf5b --- /dev/null +++ b/main/example/04_initiate_runtime_error/main.cpp @@ -0,0 +1,31 @@ +#include +#include "app.h" + +namespace tbox { +namespace main { + +void RegisterApps(Module &apps, Context &ctx) +{ + apps.add(new ::App(ctx)); +} + +std::string GetAppDescribe() +{ + return "One app sample"; +} + +std::string GetAppBuildTime() +{ + return __DATE__ " " __TIME__; +} + +void GetAppVersion(int &major, int &minor, int &rev, int &build) +{ + major = 0; + minor = 0; + rev = 1; + build = 0; +} + +} +} diff --git a/main/signal.cpp b/main/signal.cpp index 4d0bb45..726afb7 100644 --- a/main/signal.cpp +++ b/main/signal.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace tbox { namespace main { @@ -17,22 +18,8 @@ namespace { //! 打印调用栈 void PrintCallStack() { - const int buffer_size = 1024; - - void *buffer[buffer_size]; - int n = backtrace(buffer, buffer_size); - - std::stringstream ss; - char **symbols = backtrace_symbols(buffer, n); - if (symbols != NULL) { - for (int i = 0; i < n; i++) - ss << '[' << i << "] " << symbols[i] << std::endl; - free(symbols); - } else { - ss << "" << std::endl; - } - - LogFatal("\n-----call stack-----\n%s", ss.str().c_str()); + std::string &&stack_str = util::Backtrace::DumpCallStack(32, 5); + LogFatal("\n-----call stack-----\n%s", stack_str.c_str()); } //! 处理程序运行异常信号 diff --git a/sample/Makefile b/sample/Makefile index c9fb700..b22e4d3 100644 --- a/sample/Makefile +++ b/sample/Makefile @@ -20,7 +20,8 @@ LDFLAGS += \ -ltbox_log \ -ltbox_util \ -ltbox_base \ - -lpthread + -lpthread \ + -rdynamic TEST_LDFLAGS += $(LDFLAGS) diff --git a/util/Makefile b/util/Makefile index a1bad14..797633b 100644 --- a/util/Makefile +++ b/util/Makefile @@ -14,6 +14,7 @@ HEAD_FILES = \ time_counter.h \ state_machine.h \ async_pipe.h \ + backtrace.h \ CPP_SRC_FILES = \ pid_file.cpp \ @@ -26,6 +27,7 @@ CPP_SRC_FILES = \ time_counter.cpp \ state_machine.cpp \ async_pipe.cpp \ + backtrace.cpp \ CXXFLAGS := -DLOG_MODULE_ID='"util"' $(CXXFLAGS) diff --git a/base/backtrace.cpp b/util/backtrace.cpp similarity index 36% rename from base/backtrace.cpp rename to util/backtrace.cpp index ce61370..3f09483 100644 --- a/base/backtrace.cpp +++ b/util/backtrace.cpp @@ -1,19 +1,14 @@ #include -#include #include #include #include #include #include +#include #include "backtrace.h" -static uint32_t g_max_frames = 32; -static uint32_t g_skip_frames = 1; - -Backtrace::Backtrace() -{ } - -Backtrace::~Backtrace() {} +namespace tbox { +namespace util { Backtrace& Backtrace::instance() { @@ -21,82 +16,79 @@ Backtrace& Backtrace::instance() return ins; } -void Backtrace::submit() +void Backtrace::submit(std::initializer_list signals) { - for (const auto &it : signal_list_) - signal(it.signal_number, it.handler); - - std::vector tmp; - std::swap(tmp, signal_list_); - /// catch segment fault action struct sigaction sa; sigemptyset(&sa.sa_mask); - sa.sa_sigaction = Backtrace::handleSigsegv; + sa.sa_sigaction = Backtrace::HandleErrorSignal; sa.sa_flags = SA_SIGINFO; - sigaction(SIGSEGV, &sa, nullptr); -} -Backtrace& Backtrace::capture(int signo, signal_handler_t handler) -{ - signal_list_.push_back(SignalNode(signo, handler)); - return *this; + for (auto iter = signals.begin(); iter != signals.end(); ++iter) + sigaction(*iter, &sa, nullptr); } -Backtrace& Backtrace::maxFrames(unsigned int max_frames) +Backtrace& Backtrace::maxFrames(unsigned int max) { - g_max_frames = max_frames; + max_frames_ = max; return *this; } Backtrace& Backtrace::skip(unsigned int skip) { - g_skip_frames = skip; + skip_frames_ = skip; return *this; } -void Backtrace::handleSigsegv(int signal_number, siginfo_t *signal_info, void *arg) +void Backtrace::HandleErrorSignal(int signal_number, siginfo_t *signal_info, void *arg) { - (void) signal_number; (void) signal_info; (void) arg; - std::cerr << "call-stack dumped:" << std::endl; - std::string dumpinfo = Backtrace::backtraceString(g_max_frames, g_skip_frames); + std::cerr << "catch signal:" << signal_number << ", call-stack dumped:" << std::endl; + std::string dumpinfo = Backtrace::DumpCallStack(Backtrace::instance().max_frames_, Backtrace::instance().skip_frames_); std::cerr << dumpinfo << std::endl; + _exit(signal_number); } -std::string Backtrace::backtraceString(const int max_frames, const int skip) +std::string Backtrace::DumpCallStack(const unsigned int max_frames, const unsigned int skip_frames) { + char buf[1024]; + Dl_info info; + void *callstack[max_frames]; - char buf[1024] = { 0 }; std::ostringstream oss; - int number_frames = ::backtrace(callstack, max_frames); + unsigned int number_frames = ::backtrace(callstack, max_frames); char **symbols = ::backtrace_symbols(callstack, number_frames); - for (int i = skip; i < number_frames; ++i) { - Dl_info info; + constexpr const char *BACKTRACE_FORMAT = "[%d]: %s <%p>"; // callstack number | address | symbols + + for (unsigned int i = skip_frames; i < number_frames; ++i) { /// try to translate an address to symbolic information if (dladdr(callstack[i], &info)) { - char *demangled = nullptr; int status = -1; - demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); - snprintf(buf, sizeof(buf), BACKTRACE_FORMAT, i, callstack[i], status == 0 ? demangled : info.dli_sname); - if (demangled) free(demangled); - } else - snprintf(buf, sizeof(buf), BACKTRACE_FORMAT, i, callstack[i], symbols[i]); - - oss << buf; + char *demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); + snprintf(buf, sizeof(buf), BACKTRACE_FORMAT, i, (status == 0 ? demangled : info.dli_sname), callstack[i]); + if (demangled != nullptr) + free(demangled); + } else { + snprintf(buf, sizeof(buf), BACKTRACE_FORMAT, i, (symbols != nullptr ? symbols[i] : "null"), callstack[i]); + } + + oss << buf << std::endl; } - if (symbols) + if (symbols != nullptr) free(symbols); if (number_frames >= max_frames) - oss << "[truncated]\n"; + oss << "[truncated]" << std::endl; return oss.str(); } + +} +} diff --git a/base/backtrace.h b/util/backtrace.h similarity index 43% rename from base/backtrace.h rename to util/backtrace.h index 3320e03..36dea97 100644 --- a/base/backtrace.h +++ b/util/backtrace.h @@ -1,13 +1,11 @@ #ifndef _BACKTRACE_H #define _BACKTRACE_H -#include #include -#include - -#define BACKTRACE_FORMAT "%-2d: %p\t%s\n" // callstack number | address | symbols +#include -typedef void(*signal_handler_t)(int); +namespace tbox { +namespace util { /* * @brief - Aims to capture signals and formart human-readable backtrace info if @@ -19,46 +17,34 @@ typedef void(*signal_handler_t)(int); * Backtrace::instance() * .maxFrames(24) // if not set, default is 32 * .skip(2) // if not set, default is 1 - * .capture(SIGTERM, handle_term) - * .capture(SIGABRT, handle_abort) - * .capture(SIGINT, handle_interrupt) * .submit(); */ -class Backtrace -{ -private: - Backtrace(); - ~Backtrace(); - -public: +class Backtrace { + public: static Backtrace& instance(); -public: - Backtrace& capture(int signal_no, signal_handler_t handler); - Backtrace& maxFrames(unsigned int max_frames); // default is 32 + public: + Backtrace& maxFrames(unsigned int max); // default is 32 Backtrace& skip(unsigned int skip); // default is 1(will note skip) - void submit(); - -private: - static void handleSigsegv(int signal_number, siginfo_t *signal_info, void *arg); + void submit(std::initializer_list signals); /* * @brief Generate a human-readable backtrace string * * @return backtrace string */ - static std::string backtraceString(const int max_frames = 32, const int skip = 1); + static std::string DumpCallStack(const unsigned int max_frames, const unsigned int skip = 1); -private: - struct SignalNode - { - SignalNode(int s,signal_handler_t h) : signal_number(s), handler(h) { } - int signal_number; - signal_handler_t handler; - }; + private: + static void HandleErrorSignal(int signal_number, siginfo_t *signal_info, void *arg); - std::vector signal_list_; + private: + unsigned int max_frames_ = 32; + unsigned int skip_frames_ = 1; }; +} +} + #endif // _BACKTRACE_H diff --git a/util/example/backtrace/.gitignore b/util/example/backtrace/.gitignore new file mode 100644 index 0000000..ae6321f --- /dev/null +++ b/util/example/backtrace/.gitignore @@ -0,0 +1 @@ +/sample diff --git a/util/example/backtrace/Makefile b/util/example/backtrace/Makefile new file mode 100644 index 0000000..1e8e21d --- /dev/null +++ b/util/example/backtrace/Makefile @@ -0,0 +1,18 @@ +include ../build_env.mk + +CXXFLAGS += -ggdb -DLOG_MODULE_ID='"demo"' +LDFLAGS += -L.. -ltbox_util + +CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer +LDFLAGS += -fsanitize=address -static-libasan + +all : sample + +sample: sample.o + $(CXX) -o $@ $^ $(LDFLAGS) -rdynamic + +clean: + rm -rf *.o + +distclean: clean + rm -f uart_tool uart_to_uart diff --git a/util/example/backtrace/sample.cpp b/util/example/backtrace/sample.cpp new file mode 100644 index 0000000..1aa170b --- /dev/null +++ b/util/example/backtrace/sample.cpp @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +void DoAnotherThing() +{ + *static_cast(nullptr) = 0; +} + +void DoSomeThing() +{ + DoAnotherThing(); +} + +int main() { + tbox::util::Backtrace::instance().submit({SIGINT, SIGSEGV}); + std::cout << "press ctrl+c exit." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(10)); + DoSomeThing(); + return 0; +} diff --git a/util/example/build_env.mk b/util/example/build_env.mk new file mode 100644 index 0000000..5848111 --- /dev/null +++ b/util/example/build_env.mk @@ -0,0 +1,29 @@ +STAGING_DIR := ../../../.staging + +STAGING_INCLUDE := $(STAGING_DIR)/include +STAGING_LIB := $(STAGING_DIR)/lib + +CCFLAGS := -I$(STAGING_INCLUDE) -I$(CONSTANT_INCLUDE) +CFLAGS := $(CCFLAGS) -std=c99 +CXXFLAGS := $(CCFLAGS) -std=c++11 +LDFLAGS := -L$(STAGING_LIB) +INSTALL_DIR := $(STAGING_DIR) +DESTDIR := $(STAGING_DIR) +prefix := + +TOOLCHAIN_PREFIX := +AR := $(TOOLCHAIN_PREFIX)ar +AS := $(TOOLCHAIN_PREFIX)as +CXX := $(TOOLCHAIN_PREFIX)g++ +CC := $(TOOLCHAIN_PREFIX)gcc +NM := $(TOOLCHAIN_PREFIX)nm +OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy +OBJDUMP := $(TOOLCHAIN_PREFIX)objdump +STRINGS := $(TOOLCHAIN_PREFIX)strings +SSTRIP := $(TOOLCHAIN_PREFIX)sstrip +LSTRIP := $(TOOLCHAIN_PREFIX)lstrip +STRIP := $(TOOLCHAIN_PREFIX)strip + +export STAGING_INCLUDE STAGING_LIB INSTALL_DIR DESTDIR prefix +export AR AS CC NM OBJCOPY OBJDUMP CXX STRIP SSTRIP STRINGS LSTRIP +export CFLAGS CXXFLAGS LDFLAGS -- Gitee From e4d3301d70085d081186e96ec080901b1a5bc49a Mon Sep 17 00:00:00 2001 From: Hevake Date: Sat, 9 Jul 2022 17:49:38 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9main=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E7=AE=80=E5=8C=96example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../04_initiate_runtime_error/Makefile | 2 +- .../example/04_initiate_runtime_error/app.cpp | 36 ------------------- main/example/04_initiate_runtime_error/app.h | 18 ---------- .../04_initiate_runtime_error/main.cpp | 3 +- main/signal.cpp | 17 ++++----- 5 files changed, 9 insertions(+), 67 deletions(-) delete mode 100644 main/example/04_initiate_runtime_error/app.cpp delete mode 100644 main/example/04_initiate_runtime_error/app.h diff --git a/main/example/04_initiate_runtime_error/Makefile b/main/example/04_initiate_runtime_error/Makefile index d5d8065..494b843 100644 --- a/main/example/04_initiate_runtime_error/Makefile +++ b/main/example/04_initiate_runtime_error/Makefile @@ -18,7 +18,7 @@ LDFLAGS += -L.. \ CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer LDFLAGS += -fsanitize=address -static-libasan -OBJECTS := main.o app.o +OBJECTS := main.o all : $(TARGET) diff --git a/main/example/04_initiate_runtime_error/app.cpp b/main/example/04_initiate_runtime_error/app.cpp deleted file mode 100644 index a2d2738..0000000 --- a/main/example/04_initiate_runtime_error/app.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "app.h" -#include - -App::App(tbox::main::Context &ctx) : - Module("app", ctx) -{ - LogTag(); -} - -App::~App() -{ - LogTag(); -} - -bool App::onInit(const tbox::Json &cfg) -{ - LogTag(); - static_cast(nullptr)[0] = 0; - return true; -} - -bool App::onStart() -{ - LogTag(); - return true; -} - -void App::onStop() -{ - LogTag(); -} - -void App::onCleanup() -{ - LogTag(); -} diff --git a/main/example/04_initiate_runtime_error/app.h b/main/example/04_initiate_runtime_error/app.h deleted file mode 100644 index 0da3c56..0000000 --- a/main/example/04_initiate_runtime_error/app.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 -#define TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 - -#include - -class App : public tbox::main::Module -{ - public: - App(tbox::main::Context &ctx); - ~App(); - protected: - virtual bool onInit(const tbox::Json &cfg) override; - virtual bool onStart() override; - virtual void onStop() override; - virtual void onCleanup() override; -}; - -#endif //TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 diff --git a/main/example/04_initiate_runtime_error/main.cpp b/main/example/04_initiate_runtime_error/main.cpp index 799cf5b..7ced007 100644 --- a/main/example/04_initiate_runtime_error/main.cpp +++ b/main/example/04_initiate_runtime_error/main.cpp @@ -1,12 +1,11 @@ #include -#include "app.h" namespace tbox { namespace main { void RegisterApps(Module &apps, Context &ctx) { - apps.add(new ::App(ctx)); + static_cast(nullptr)[0] = 0; } std::string GetAppDescribe() diff --git a/main/signal.cpp b/main/signal.cpp index 726afb7..fa6fa5c 100644 --- a/main/signal.cpp +++ b/main/signal.cpp @@ -15,21 +15,18 @@ extern std::function error_exit_func; //!< 出错异常退出前要做 namespace { -//! 打印调用栈 -void PrintCallStack() -{ - std::string &&stack_str = util::Backtrace::DumpCallStack(32, 5); - LogFatal("\n-----call stack-----\n%s", stack_str.c_str()); -} - //! 处理程序运行异常信号 void OnErrorSignal(int signo) { + const std::string &stack_str = util::Backtrace::DumpCallStack(32, 5); + LogFatal("Receive signal %d", signo); - PrintCallStack(); - if (error_exit_func) + LogFatal("\n-----call stack-----\n%s", stack_str.c_str()); + + if (error_exit_func) //! 执行一些善后处理 error_exit_func(); - exit(EXIT_FAILURE); + + ::exit(EXIT_FAILURE); } void OnWarnSignal(int signo) -- Gitee From ae43943a5df65600d611269301a7f883bc8c4d52 Mon Sep 17 00:00:00 2001 From: Hevake Date: Sat, 9 Jul 2022 18:02:07 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BC=98=E5=8C=96backtrace=EF=BC=9B?= =?UTF-8?q?=E5=B0=86=E7=A4=BA=E4=BE=8B=E7=A8=8B=E5=BA=8F=E6=94=B9=E6=88=90?= =?UTF-8?q?=E9=80=92=E5=BD=92=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/backtrace.cpp | 2 +- util/backtrace.h | 8 ++++---- util/example/backtrace/sample.cpp | 25 ++++++++++++++----------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/util/backtrace.cpp b/util/backtrace.cpp index 3f09483..de9dcba 100644 --- a/util/backtrace.cpp +++ b/util/backtrace.cpp @@ -34,7 +34,7 @@ Backtrace& Backtrace::maxFrames(unsigned int max) return *this; } -Backtrace& Backtrace::skip(unsigned int skip) +Backtrace& Backtrace::skipFrames(unsigned int skip) { skip_frames_ = skip; return *this; diff --git a/util/backtrace.h b/util/backtrace.h index 36dea97..93ebc84 100644 --- a/util/backtrace.h +++ b/util/backtrace.h @@ -15,9 +15,9 @@ namespace util { * # Examples: * * Backtrace::instance() - * .maxFrames(24) // if not set, default is 32 - * .skip(2) // if not set, default is 1 - * .submit(); + * .maxFrames(24) // if not set, default is 32 + * .skipFrames(2) // if not set, default is 1 + * .submit({SIGSEGV, SIGABRT}); // submit SIGSEGV and SIGABRT as error */ class Backtrace { public: @@ -25,7 +25,7 @@ class Backtrace { public: Backtrace& maxFrames(unsigned int max); // default is 32 - Backtrace& skip(unsigned int skip); // default is 1(will note skip) + Backtrace& skipFrames(unsigned int skip); // default is 1(will note skip) void submit(std::initializer_list signals); diff --git a/util/example/backtrace/sample.cpp b/util/example/backtrace/sample.cpp index 1aa170b..274e6ad 100644 --- a/util/example/backtrace/sample.cpp +++ b/util/example/backtrace/sample.cpp @@ -3,20 +3,23 @@ #include #include -void DoAnotherThing() +void DoSomeThing(int deep) { - *static_cast(nullptr) = 0; -} - -void DoSomeThing() -{ - DoAnotherThing(); + if (deep == 0) + *static_cast(nullptr) = 0; //! 触发异常 + else + DoSomeThing(deep - 1); } int main() { - tbox::util::Backtrace::instance().submit({SIGINT, SIGSEGV}); - std::cout << "press ctrl+c exit." << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(10)); - DoSomeThing(); + tbox::util::Backtrace::instance() + .maxFrames(10) + .skipFrames(2) + .submit({SIGINT, SIGSEGV}); + + std::cout << "sleep 5sec, press ctrl+c exit." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(5)); + + DoSomeThing(40); return 0; } -- Gitee From 429addf7de38fa5fbddbc1945572c29727f5c2ef Mon Sep 17 00:00:00 2001 From: Hevake Date: Sat, 9 Jul 2022 18:03:44 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=B0=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/example/backtrace/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/example/backtrace/Makefile b/util/example/backtrace/Makefile index 1e8e21d..6b54048 100644 --- a/util/example/backtrace/Makefile +++ b/util/example/backtrace/Makefile @@ -15,4 +15,4 @@ clean: rm -rf *.o distclean: clean - rm -f uart_tool uart_to_uart + rm -f sample -- Gitee