Browse Source

[Feature] Use backward-cpp instead of manual libunwind stuff

tags/3.7.1
Vsevolod Stakhov 7 months ago
parent
commit
1adcfb1e23
No account linked to committer's email address

+ 2
- 9
CMakeLists.txt View File

@@ -56,7 +56,7 @@ OPTION(ENABLE_CLANG_PLUGIN "Enable clang static analysing plugin [default: OFF]"
OPTION(ENABLE_PCRE2 "Enable pcre2 instead of pcre [default: ON]" ON)
OPTION(ENABLE_JEMALLOC "Build rspamd with jemalloc allocator [default: OFF]" OFF)
OPTION(ENABLE_UTILS "Build rspamd internal utils [default: OFF]" OFF)
OPTION(ENABLE_LIBUNWIND "Use libunwind to print crash traces [default: OFF]" OFF)
OPTION(ENABLE_LIBUNWIND "Obsoleted [default: OFF]" OFF)
OPTION(ENABLE_LUA_TRACE "Trace all Lua C API invocations [default: OFF]" OFF)
OPTION(ENABLE_LUA_REPL "Enables Lua repl (requires C++11 compiler) [default: ON]" ON)
OPTION(ENABLE_FASTTEXT "Link with FastText library [default: OFF]" OFF)
@@ -208,14 +208,6 @@ IF (ENABLE_JEMALLOC MATCHES "ON" AND NOT SANITIZE)
SET(WITH_JEMALLOC "1")
ENDIF ()

IF (ENABLE_LIBUNWIND MATCHES "ON")
ProcessPackage(LIBUNWIND LIBRARY unwind INCLUDE libunwind.h INCLUDE_SUFFIXES include/libunwind
ROOT ${LIBUNWIND_ROOT_DIR} MODULES libunwind)
SET(WITH_LIBUNWIND "1")
ELSE ()
CHECK_SYMBOL_EXISTS(backtrace "execinfo.h" HAVE_BACKTRACE)
ENDIF ()

ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h
INCLUDE_SUFFIXES include/glib include/glib-2.0
ROOT ${GLIB_ROOT_DIR} MODULES glib-2.0>=2.28)
@@ -633,6 +625,7 @@ ADD_SUBDIRECTORY(contrib/libev)
ADD_SUBDIRECTORY(contrib/kann)
ADD_SUBDIRECTORY(contrib/fastutf8)
ADD_SUBDIRECTORY(contrib/google-ced)
ADD_SUBDIRECTORY(contrib/backward-cpp)
IF (SYSTEM_FMT MATCHES "OFF")
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/contrib/fmt/include")
ELSE ()

+ 1
- 2
config.h.in View File

@@ -111,11 +111,10 @@
#cmakedefine WITH_PCRE2 1
#cmakedefine WITH_SNOWBALL 1
#cmakedefine WITH_SQLITE 1
#cmakedefine WITH_LIBUNWIND 1
#cmakedefine WITH_LUA_TRACE 1
#cmakedefine WITH_LUA_REPL 1
#cmakedefine WITH_FASTTEXT 1
#cmakedefine HAVE_BACKTRACE 1
#cmakedefine BACKWARD_ENABLE 1

#cmakedefine DISABLE_PTHREAD_MUTEX 1


+ 39
- 37
contrib/DEPENDENCY_INFO.md View File

@@ -1,39 +1,41 @@
# Rspamd Dependency Info

| Name | Version | License | Patched | Notes |
|------------------------|---------|---------------------| --- | --- |
| aho-corasick | ? | LGPL-3.0 | YES | lowercase support |
| cdb | 1.1.0 | Public Domain / CC0 | NO | |
| hiredis | 0.13.3 | BSD-3-Clause | YES | many changes |
| libev | 4.33 | BSD-2-Clause | YES | many changes |
| lc-btrie | ? | BSD-3-Clause | YES | mempool support |
| libottery | ? | Public Domain / CC0 | YES | many changes |
| librdns | ? | BSD-2-Clause | YES | |
| libucl | ? | BSD-2-Clause | YES | |
| replxx | 6d93360 | BSD-2-Clause | YES | libicu usage |
| lua-argparse | 0.7.1 | MIT | NO | |
| lua-bit | 1.0.2 | MIT | YES | build fixes |
| lua-fun | ? | MIT | YES | rspamd text |
| lua-lpeg | 1.0 | MIT | YES | rspamd text + alloc|
| lua-moses | ? | MIT | NO | |
| lua-lupa | ? | MIT | NO | |
| lua-tableshape | 2.6.0 | MIT | NO | |
| mumhash | ? | MIT | NO | |
| ngx-http-parser | 2.2.0 | MIT | YES | spamc support |
| Mozilla-PublicSuffix | ? | MIT | NO | |
| snowball | ? | BSD-3-Clause | NO | |
| t1ha | ? | Zlib | NO | |
| uthash | 1.9.8 | BSD | YES | |
| xxhash | 0.8.1 | BSD | NO | |
| zstd | 1.5.4 | BSD | YES | build fixes only |
| google-ced | 37529e6 | Apache 2 | YES | build fixes |
| kann | ? | MIT | YES | blas/lapack changes|
| fpconv | ? | Boost | YES | many changes |
| fastutf8 | ? | MIT | YES | many changes |
| expected | v1.0 | Public Domain / CC0 | NO | |
| frozen | 1.0.1 | Apache 2 | NO | |
| fmt | 10.0.0 | MIT | NO | |
| doctest | 2.4.6 | MIT | NO | |
| function2 | 4.1.0 | Boost | NO | |
| ankerl/svector | 1.0.2 | MIT | NO | |
| ankerl/unordered_dense | 2.0.1 | MIT | NO | |
| Name | Version | License | Patched | Notes |
|------------------------|---------|---------------------|---------|---------------------|
| aho-corasick | ? | LGPL-3.0 | YES | lowercase support |
| cdb | 1.1.0 | Public Domain / CC0 | NO | |
| hiredis | 0.13.3 | BSD-3-Clause | YES | many changes |
| libev | 4.33 | BSD-2-Clause | YES | many changes |
| lc-btrie | ? | BSD-3-Clause | YES | mempool support |
| libottery | ? | Public Domain / CC0 | YES | many changes |
| librdns | ? | BSD-2-Clause | YES | |
| libucl | ? | BSD-2-Clause | YES | |
| replxx | 6d93360 | BSD-2-Clause | YES | libicu usage |
| lua-argparse | 0.7.1 | MIT | NO | |
| lua-bit | 1.0.2 | MIT | YES | build fixes |
| lua-fun | ? | MIT | YES | rspamd text |
| lua-lpeg | 1.0 | MIT | YES | rspamd text + alloc |
| lua-moses | ? | MIT | NO | |
| lua-lupa | ? | MIT | NO | |
| lua-tableshape | 2.6.0 | MIT | NO | |
| mumhash | ? | MIT | NO | |
| ngx-http-parser | 2.2.0 | MIT | YES | spamc support |
| Mozilla-PublicSuffix | ? | MIT | NO | |
| snowball | ? | BSD-3-Clause | NO | |
| t1ha | ? | Zlib | NO | |
| uthash | 1.9.8 | BSD | YES | |
| xxhash | 0.8.1 | BSD | NO | |
| zstd | 1.5.4 | BSD | YES | build fixes only |
| google-ced | 37529e6 | Apache 2 | YES | build fixes |
| kann | ? | MIT | YES | blas/lapack changes |
| fpconv | ? | Boost | YES | many changes |
| fastutf8 | ? | MIT | YES | many changes |
| expected | v1.0 | Public Domain / CC0 | NO | |
| frozen | 1.0.1 | Apache 2 | NO | |
| fmt | 10.0.0 | MIT | NO | |
| doctest | 2.4.6 | MIT | NO | |
| function2 | 4.1.0 | Boost | NO | |
| ankerl/svector | 1.0.2 | MIT | NO | |
| ankerl/unordered_dense | 2.0.1 | MIT | NO | |
| backward-cpp | 1.6 | MIT | NO | |


+ 247
- 0
contrib/backward-cpp/BackwardConfig.cmake View File

@@ -0,0 +1,247 @@
#
# BackwardMacros.cmake
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

###############################################################################
# OPTIONS
###############################################################################

set(STACK_WALKING_UNWIND TRUE CACHE BOOL
"Use compiler's unwind API")
set(STACK_WALKING_BACKTRACE FALSE CACHE BOOL
"Use backtrace from (e)glibc for stack walking")
set(STACK_WALKING_LIBUNWIND FALSE CACHE BOOL
"Use libunwind for stack walking")

set(STACK_DETAILS_AUTO_DETECT TRUE CACHE BOOL
"Auto detect backward's stack details dependencies")

set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE CACHE BOOL
"Use backtrace from (e)glibc for symbols resolution")
set(STACK_DETAILS_DW FALSE CACHE BOOL
"Use libdw to read debug info")
set(STACK_DETAILS_BFD FALSE CACHE BOOL
"Use libbfd to read debug info")
set(STACK_DETAILS_DWARF FALSE CACHE BOOL
"Use libdwarf/libelf to read debug info")

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT DEFINED BACKWARD_TESTS)
# If this is a top level CMake project, we most lixely want the tests
set(BACKWARD_TESTS ON CACHE BOOL "Enable tests")
else()
set(BACKWARD_TESTS OFF CACHE BOOL "Enable tests")
endif()
###############################################################################
# CONFIGS
###############################################################################
include(FindPackageHandleStandardArgs)

if (STACK_WALKING_LIBUNWIND)
# libunwind works on the macOS without having to add special include
# paths or libraries
if (NOT APPLE)
find_path(LIBUNWIND_INCLUDE_DIR NAMES "libunwind.h")
find_library(LIBUNWIND_LIBRARY unwind)

if (LIBUNWIND_LIBRARY)
include(CheckSymbolExists)
check_symbol_exists(UNW_INIT_SIGNAL_FRAME libunwind.h HAVE_UNW_INIT_SIGNAL_FRAME)
if (NOT HAVE_UNW_INIT_SIGNAL_FRAME)
message(STATUS "libunwind does not support unwinding from signal handler frames")
endif()
endif()

set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR})
set(LIBDWARF_LIBRARIES ${LIBUNWIND_LIBRARY})
find_package_handle_standard_args(libunwind DEFAULT_MSG
LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR)
mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY)
list(APPEND _BACKWARD_LIBRARIES ${LIBUNWIND_LIBRARY})
endif()

# Disable other unwinders if libunwind is found
set(STACK_WALKING_UNWIND FALSE)
set(STACK_WALKING_BACKTRACE FALSE)
endif()

if (${STACK_DETAILS_AUTO_DETECT})
if(NOT CMAKE_VERSION VERSION_LESS 3.17)
set(_name_mismatched_arg NAME_MISMATCHED)
endif()
# find libdw
find_path(LIBDW_INCLUDE_DIR NAMES "elfutils/libdw.h" "elfutils/libdwfl.h")
find_library(LIBDW_LIBRARY dw)
set(LIBDW_INCLUDE_DIRS ${LIBDW_INCLUDE_DIR} )
set(LIBDW_LIBRARIES ${LIBDW_LIBRARY} )
find_package_handle_standard_args(libdw ${_name_mismatched_arg}
REQUIRED_VARS LIBDW_LIBRARY LIBDW_INCLUDE_DIR)
mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY)

# find libbfd
find_path(LIBBFD_INCLUDE_DIR NAMES "bfd.h")
find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
find_library(LIBBFD_LIBRARY bfd)
find_library(LIBDL_LIBRARY dl)
set(LIBBFD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
set(LIBBFD_LIBRARIES ${LIBBFD_LIBRARY} ${LIBDL_LIBRARY})
find_package_handle_standard_args(libbfd ${_name_mismatched_arg}
REQUIRED_VARS LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR
LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY
LIBDL_INCLUDE_DIR LIBDL_LIBRARY)

# find libdwarf
find_path(LIBDWARF_INCLUDE_DIR NAMES "libdwarf.h" PATH_SUFFIXES libdwarf)
find_path(LIBELF_INCLUDE_DIR NAMES "libelf.h")
find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
find_library(LIBDWARF_LIBRARY dwarf)
find_library(LIBELF_LIBRARY elf)
find_library(LIBDL_LIBRARY dl)
set(LIBDWARF_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARY} ${LIBELF_LIBRARY} ${LIBDL_LIBRARY})
find_package_handle_standard_args(libdwarf ${_name_mismatched_arg}
REQUIRED_VARS LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR
LIBELF_LIBRARY LIBELF_INCLUDE_DIR
LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
mark_as_advanced(LIBDWARF_INCLUDE_DIR LIBDWARF_LIBRARY
LIBELF_INCLUDE_DIR LIBELF_LIBRARY
LIBDL_INCLUDE_DIR LIBDL_LIBRARY)

if (LIBDW_FOUND)
LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDW_INCLUDE_DIRS})
LIST(APPEND _BACKWARD_LIBRARIES ${LIBDW_LIBRARIES})
set(STACK_DETAILS_DW TRUE)
set(STACK_DETAILS_BFD FALSE)
set(STACK_DETAILS_DWARF FALSE)
set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
elseif(LIBBFD_FOUND)
LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIRS})
LIST(APPEND _BACKWARD_LIBRARIES ${LIBBFD_LIBRARIES})

# If we attempt to link against static bfd, make sure to link its dependencies, too
get_filename_component(bfd_lib_ext "${LIBBFD_LIBRARY}" EXT)
if (bfd_lib_ext STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")
list(APPEND _BACKWARD_LIBRARIES iberty z)
endif()

set(STACK_DETAILS_DW FALSE)
set(STACK_DETAILS_BFD TRUE)
set(STACK_DETAILS_DWARF FALSE)
set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
elseif(LIBDWARF_FOUND)
LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIRS})
LIST(APPEND _BACKWARD_LIBRARIES ${LIBDWARF_LIBRARIES})

set(STACK_DETAILS_DW FALSE)
set(STACK_DETAILS_BFD FALSE)
set(STACK_DETAILS_DWARF TRUE)
set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
else()
set(STACK_DETAILS_DW FALSE)
set(STACK_DETAILS_BFD FALSE)
set(STACK_DETAILS_DWARF FALSE)
set(STACK_DETAILS_BACKTRACE_SYMBOL TRUE)
endif()
else()
if (STACK_DETAILS_DW)
LIST(APPEND _BACKWARD_LIBRARIES dw)
endif()

if (STACK_DETAILS_BFD)
LIST(APPEND _BACKWARD_LIBRARIES bfd dl)
endif()

if (STACK_DETAILS_DWARF)
LIST(APPEND _BACKWARD_LIBRARIES dwarf elf)
endif()
endif()

macro(map_definitions var_prefix define_prefix)
foreach(def ${ARGN})
if (${${var_prefix}${def}})
LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=1")
else()
LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=0")
endif()
endforeach()
endmacro()

if (NOT _BACKWARD_DEFINITIONS)
map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND LIBUNWIND BACKTRACE)
map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW BFD DWARF)
endif()

if(WIN32)
list(APPEND _BACKWARD_LIBRARIES dbghelp psapi)
if(MINGW)
set(MINGW_MSVCR_LIBRARY "msvcr90$<$<CONFIG:DEBUG>:d>" CACHE STRING "Mingw MSVC runtime import library")
list(APPEND _BACKWARD_LIBRARIES ${MINGW_MSVCR_LIBRARY})
endif()
endif()

set(BACKWARD_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")

set(BACKWARD_HAS_EXTERNAL_LIBRARIES FALSE)
set(FIND_PACKAGE_REQUIRED_VARS BACKWARD_INCLUDE_DIR)
if(DEFINED _BACKWARD_LIBRARIES)
set(BACKWARD_HAS_EXTERNAL_LIBRARIES TRUE)
list(APPEND FIND_PACKAGE_REQUIRED_VARS _BACKWARD_LIBRARIES)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Backward
REQUIRED_VARS ${FIND_PACKAGE_REQUIRED_VARS}
)
list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR})

macro(add_backward target)
target_include_directories(${target} PRIVATE ${BACKWARD_INCLUDE_DIRS})
set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS ${BACKWARD_DEFINITIONS})
set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES ${BACKWARD_LIBRARIES})
endmacro()

set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "_BACKWARD_INCLUDE_DIRS")
set(BACKWARD_DEFINITIONS ${_BACKWARD_DEFINITIONS} CACHE INTERNAL "BACKWARD_DEFINITIONS")
set(BACKWARD_LIBRARIES ${_BACKWARD_LIBRARIES} CACHE INTERNAL "BACKWARD_LIBRARIES")
mark_as_advanced(BACKWARD_INCLUDE_DIRS BACKWARD_DEFINITIONS BACKWARD_LIBRARIES)

# Expand each definition in BACKWARD_DEFINITIONS to its own cmake var and export
# to outer scope
foreach(var ${BACKWARD_DEFINITIONS})
string(REPLACE "=" ";" var_as_list ${var})
list(GET var_as_list 0 var_name)
list(GET var_as_list 1 var_value)
set(${var_name} ${var_value})
mark_as_advanced(${var_name})
endforeach()

if (NOT TARGET Backward::Backward)
add_library(Backward::Backward INTERFACE IMPORTED)
set_target_properties(Backward::Backward PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BACKWARD_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS "${BACKWARD_DEFINITIONS}"
)
if(BACKWARD_HAS_EXTERNAL_LIBRARIES)
set_target_properties(Backward::Backward PROPERTIES
INTERFACE_LINK_LIBRARIES "${BACKWARD_LIBRARIES}"
)
endif()
endif()

+ 139
- 0
contrib/backward-cpp/CMakeLists.txt View File

@@ -0,0 +1,139 @@
#
# CMakeLists.txt
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

cmake_minimum_required(VERSION 3.0)
project(backward CXX)

# Introduce variables:
# * CMAKE_INSTALL_LIBDIR
# * CMAKE_INSTALL_BINDIR
# * CMAKE_INSTALL_INCLUDEDIR
include(GNUInstallDirs)

include(BackwardConfig.cmake)

# check if compiler is nvcc or nvcc_wrapper
set(COMPILER_IS_NVCC false)
get_filename_component(COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME)
if (COMPILER_NAME MATCHES "^nvcc")
set(COMPILER_IS_NVCC true)
endif()

if (DEFINED ENV{OMPI_CXX} OR DEFINED ENV{MPICH_CXX})
if ( ($ENV{OMPI_CXX} MATCHES "nvcc") OR ($ENV{MPICH_CXX} MATCHES "nvcc") )
set(COMPILER_IS_NVCC true)
endif()
endif()

# set CXX standard
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_STANDARD 11)
if (${COMPILER_IS_NVCC})
# GNU CXX extensions are not supported by nvcc
set(CMAKE_CXX_EXTENSIONS OFF)
endif()

###############################################################################
# COMPILER FLAGS
###############################################################################

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
if (NOT ${COMPILER_IS_NVCC})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
endif()

###############################################################################
# BACKWARD OBJECT
###############################################################################

add_library(backward_object OBJECT backward.cpp)
target_compile_definitions(backward_object PRIVATE ${BACKWARD_DEFINITIONS})
target_include_directories(backward_object PRIVATE ${BACKWARD_INCLUDE_DIRS})
set(BACKWARD_ENABLE $<TARGET_OBJECTS:backward_object> CACHE STRING
"Link with this object to setup backward automatically")


###############################################################################
# BACKWARD LIBRARY (Includes backward.cpp)
###############################################################################
option(BACKWARD_SHARED "Build dynamic backward-cpp shared lib" OFF)

if(BACKWARD_SHARED)
set(libtype SHARED)
endif()
add_library(backward ${libtype} backward.cpp)
target_compile_definitions(backward PUBLIC ${BACKWARD_DEFINITIONS})
target_include_directories(backward PUBLIC ${BACKWARD_INCLUDE_DIRS})

###############################################################################
# TESTS
###############################################################################

if(BACKWARD_TESTS)
enable_testing()

add_library(test_main OBJECT test/_test_main.cpp)

macro(backward_add_test src)
get_filename_component(name ${src} NAME_WE)
set(test_name "test_${name}")

add_executable(${test_name} ${src} ${ARGN} $<TARGET_OBJECTS:test_main>)

target_link_libraries(${test_name} PRIVATE Backward::Backward)

add_test(NAME ${name} COMMAND ${test_name})
endmacro()

# Tests without backward.cpp
set(TESTS
test
stacktrace
rectrace
select_signals
)

foreach(test ${TESTS})
backward_add_test(test/${test}.cpp)
endforeach()

# Tests with backward.cpp
set(TESTS
suicide
)

foreach(test ${TESTS})
backward_add_test(test/${test}.cpp ${BACKWARD_ENABLE})
endforeach()
endif()

install(
FILES "backward.hpp"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
FILES "BackwardConfig.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/backward
)

+ 42
- 0
contrib/backward-cpp/backward.cpp View File

@@ -0,0 +1,42 @@
// Pick your poison.
//
// On GNU/Linux, you have few choices to get the most out of your stack trace.
//
// By default you get:
// - object filename
// - function name
//
// In order to add:
// - source filename
// - line and column numbers
// - source code snippet (assuming the file is accessible)

// Install one of the following libraries then uncomment one of the macro (or
// better, add the detection of the lib and the macro definition in your build
// system)

// - apt-get install libdw-dev ...
// - g++/clang++ -ldw ...
// #define BACKWARD_HAS_DW 1

// - apt-get install binutils-dev ...
// - g++/clang++ -lbfd ...
// #define BACKWARD_HAS_BFD 1

// - apt-get install libdwarf-dev ...
// - g++/clang++ -ldwarf ...
// #define BACKWARD_HAS_DWARF 1

// Regardless of the library you choose to read the debug information,
// for potentially more detailed stack traces you can use libunwind
// - apt-get install libunwind-dev
// - g++/clang++ -lunwind
// #define BACKWARD_HAS_LIBUNWIND 1

#include "backward.hpp"

namespace backward {

backward::SignalHandling sh;

} // namespace backward

+ 4464
- 0
contrib/backward-cpp/backward.hpp
File diff suppressed because it is too large
View File


+ 1
- 0
debian/control View File

@@ -13,6 +13,7 @@ Build-Depends: cmake,
libsqlite3-dev,
libssl-dev (>= 1.0),
libunwind-dev | libunwind-13-dev,
libdwarf-dev,
perl,
ragel,
zlib1g-dev

+ 1
- 1
rpm/rspamd.spec View File

@@ -65,6 +65,7 @@ BuildRequires: pcre2-devel
BuildRequires: ragel
BuildRequires: sqlite-devel
BuildRequires: systemd
BuildRequires: libdwarf-devel
Requires(pre): shadow-utils
Requires(post): systemd
Requires(preun): systemd
@@ -136,7 +137,6 @@ rm -f %{_builddir}/luajit-build/lib/*.so || true
-DWANT_SYSTEMD_UNITS=ON \
-DNO_SHARED=ON \
-DDEBIAN_BUILD=1 \
-DENABLE_LIBUNWIND=ON \
%ifarch x86_64 amd64 arm64 aarch64
-DENABLE_HYPERSCAN=ON \
%endif

+ 1
- 1
src/CMakeLists.txt View File

@@ -228,7 +228,7 @@ ENDIF()

TARGET_LINK_LIBRARIES(rspamd-server ${RSPAMD_REQUIRED_LIBRARIES})

ADD_EXECUTABLE(rspamd ${RSPAMDSRC} ${CMAKE_CURRENT_BINARY_DIR}/workers.c ${CMAKE_CURRENT_BINARY_DIR}/config.h)
ADD_EXECUTABLE(rspamd ${RSPAMDSRC} ${CMAKE_CURRENT_BINARY_DIR}/workers.c ${CMAKE_CURRENT_BINARY_DIR}/config.h ${BACKWARD_ENABLE})
SET_TARGET_PROPERTIES(rspamd PROPERTIES LINKER_LANGUAGE CXX)
SET_TARGET_PROPERTIES(rspamd-server PROPERTIES LINKER_LANGUAGE CXX)
IF(NOT DEBIAN_BUILD)

+ 1
- 0
src/libserver/CMakeLists.txt View File

@@ -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

+ 61
- 0
src/libserver/backtrace.cxx View File

@@ -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
}

+ 7
- 73
src/libserver/worker_util.c View File

@@ -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");

Loading…
Cancel
Save