aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/CMakeLists.txt1
-rw-r--r--src/libserver/backtrace.cxx61
-rw-r--r--src/libserver/worker_util.c80
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");