diff options
Diffstat (limited to 'src/libserver')
-rw-r--r-- | src/libserver/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/libserver/backtrace.cxx | 61 | ||||
-rw-r--r-- | src/libserver/worker_util.c | 80 |
3 files changed, 69 insertions, 73 deletions
diff --git a/src/libserver/CMakeLists.txt b/src/libserver/CMakeLists.txt index 56cc2444d..dd17865de 100644 --- a/src/libserver/CMakeLists.txt +++ b/src/libserver/CMakeLists.txt @@ -43,6 +43,7 @@ SET(LIBRSPAMDSERVERSRC ${CMAKE_CURRENT_SOURCE_DIR}/html/html.cxx ${CMAKE_CURRENT_SOURCE_DIR}/html/html_tests.cxx ${CMAKE_CURRENT_SOURCE_DIR}/hyperscan_tools.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/backtrace.cxx ${LIBCSSSRC}) # Librspamd-server diff --git a/src/libserver/backtrace.cxx b/src/libserver/backtrace.cxx new file mode 100644 index 000000000..6507b964e --- /dev/null +++ b/src/libserver/backtrace.cxx @@ -0,0 +1,61 @@ +/* + * Copyright 2023 Vsevolod Stakhov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" + +#ifdef BACKWARD_ENABLE + +#include "contrib/backward-cpp/backward.hpp" +#include "fmt/core.h" +#include "logger.h" + +namespace rspamd { + +void log_backtrace(void) +{ + using namespace backward; + StackTrace st; + st.load_here(128); + + TraceResolver tr; + tr.load_stacktrace(st); + + for (auto i = 0ul; i < st.size(); ++i) { + auto trace = tr.resolve(st[i]); + auto trace_line = fmt::format("#{}: [{}]: ", i, trace.addr); + + if (!trace.source.filename.empty()) { + trace_line += fmt::format("{}:{} in {}", trace.source.filename, trace.source.line, trace.source.function); + } + else { + trace_line += fmt::format("{} in {}", trace.object_filename, trace.object_function); + } + + msg_err("%s", trace_line.c_str()); + } +} + +}// namespace rspamd +#endif + +extern "C" void rspamd_print_crash(void); + +void rspamd_print_crash(void) +{ +#ifdef BACKWARD_ENABLE + rspamd::log_backtrace(); +#endif +}
\ No newline at end of file diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 32e1e9ae0..8edfe0cdb 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -43,12 +43,6 @@ #endif #include "zlib.h" -#ifdef WITH_LIBUNWIND -#define UNW_LOCAL_ONLY 1 -#include <libunwind.h> -#define UNWIND_BACKTRACE_DEPTH 256 -#endif - #ifdef HAVE_UCONTEXT_H #include <ucontext.h> #elif defined(HAVE_SYS_UCONTEXT_H) @@ -1610,71 +1604,6 @@ void rspamd_worker_init_monitored(struct rspamd_worker *worker, #ifdef HAVE_SA_SIGINFO -#ifdef WITH_LIBUNWIND -static void -rspamd_print_crash(ucontext_t *_uap) -{ - unw_cursor_t cursor; - unw_context_t uc; - unw_word_t ip, off, sp; - guint level; - gint ret; - - unw_getcontext(&uc); - if ((ret = unw_init_local(&cursor, &uc)) != 0) { - msg_err("unw_init_local: %d", ret); - - return; - } - - level = 0; - ret = 0; - - for (;;) { - char name[128]; - - if (level >= UNWIND_BACKTRACE_DEPTH) { - break; - } - - unw_get_reg(&cursor, UNW_REG_IP, &ip); - ret = unw_get_proc_name(&cursor, name, sizeof(name), &off); - - if (ret == 0) { - msg_err("%d: 0x%xl: %s()+0x%xl", - level, (unsigned long) ip, name, (unsigned long) off); - } - else { - msg_err("%d: %0x%xl: <unknown>", level, (unsigned long) ip); - } - - level++; - ret = unw_step(&cursor); - - if (ret <= 0) { - break; - } - } - - if (ret < 0) { - msg_err("unw_step_ptr: %d", ret); - } -} -#elif defined(HAVE_BACKTRACE) -#include <execinfo.h> -static void -rspamd_print_crash(ucontext_t *_uap) -{ - void *callstack[128]; - int i, frames = backtrace(callstack, 128); - char **strs = backtrace_symbols(callstack, frames); - for (i = 0; i < frames; ++i) { - msg_err("%d: %s", i, strs[i]); - } - free(strs); -} -#endif - static struct rspamd_main *saved_main = NULL; static gboolean rspamd_crash_propagate(gpointer key, gpointer value, gpointer unused) @@ -1687,6 +1616,11 @@ rspamd_crash_propagate(gpointer key, gpointer value, gpointer unused) return TRUE; } +#ifdef BACKWARD_ENABLE +/* See backtrace.cxx */ +extern void rspamd_print_crash(void); +#endif + static void rspamd_crash_sig_handler(int sig, siginfo_t *info, void *ctx) { @@ -1699,8 +1633,8 @@ rspamd_crash_sig_handler(int sig, siginfo_t *info, void *ctx) "pid: %P, trace: ", sig, strsignal(sig), pid); (void) uap; -#if defined(WITH_LIBUNWIND) || defined(HAVE_BACKTRACE) - rspamd_print_crash(uap); +#ifdef BACKWARD_ENABLE + rspamd_print_crash(); #endif msg_err("please see Rspamd FAQ to learn how to dump core files and how to " "fill a bug report"); |