diff --git a/CMakeLists.txt b/CMakeLists.txt index f3900a8f4c6..1719aa0c38c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,8 +29,8 @@ option(ENABLE_STATIC_LIBSTDCXX "link kvrocks with static library of libstd++ ins option(ENABLE_LUAJIT "enable use of luaJIT instead of lua" ON) option(ENABLE_OPENSSL "enable openssl to support tls connection" OFF) option(ENABLE_IPO "enable interprocedural optimization" ON) -option(ENABLE_UNWIND "enable libunwind in glog" ON) option(ENABLE_SPEEDB "enable speedb instead of rocksdb" OFF) +set(SYMBOLIZE_BACKEND "" CACHE STRING "symbolization backend library for cpptrace (libbacktrace, libdwarf, or empty)") set(PORTABLE 0 CACHE STRING "build a portable binary (disable arch-specific optimizations)") # TODO: set ENABLE_NEW_ENCODING to ON when we are ready option(ENABLE_NEW_ENCODING "enable new encoding (#1033) for storing 64bit size and expire time in milliseconds" ON) @@ -169,6 +169,7 @@ include(cmake/span.cmake) include(cmake/trie.cmake) include(cmake/pegtl.cmake) include(cmake/rangev3.cmake) +include(cmake/cpptrace.cmake) if (ENABLE_LUAJIT) include(cmake/luajit.cmake) @@ -203,6 +204,7 @@ list(APPEND EXTERNAL_LIBS span-lite) list(APPEND EXTERNAL_LIBS tsl_hat_trie) list(APPEND EXTERNAL_LIBS pegtl) list(APPEND EXTERNAL_LIBS range-v3) +list(APPEND EXTERNAL_LIBS cpptrace::cpptrace) # Add git sha to version.h find_package(Git REQUIRED) diff --git a/NOTICE b/NOTICE index 7e674d153d6..3b2a470bf3c 100644 --- a/NOTICE +++ b/NOTICE @@ -71,6 +71,7 @@ The text of each license is also included in licenses/LICENSE-[project].txt * lua(https://github.com/KvrocksLabs/lua, alternative to LuaJIT) * hat-trie(https://github.com/Tessil/hat-trie) * pegtl(https://github.com/taocpp/PEGTL, NOTE: changed to Boost Software License Version 1.0 in main branch) +* cpptrace(https://github.com/jeremy-rifkin/cpptrace) ================================================================ Boost Software License Version 1.0 diff --git a/cmake/cpptrace.cmake b/cmake/cpptrace.cmake new file mode 100644 index 00000000000..5fc0189e4e7 --- /dev/null +++ b/cmake/cpptrace.cmake @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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_guard() + +include(cmake/utils.cmake) + +FetchContent_DeclareGitHubWithMirror(cpptrace + jeremy-rifkin/cpptrace v0.6.0 + MD5=924df247ba4a151d243130060c2c0a04 +) + +if (SYMBOLIZE_BACKEND STREQUAL "libbacktrace") + set(CPPTRACE_BACKEND_OPTION "CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE=ON") +elseif (SYMBOLIZE_BACKEND STREQUAL "libdwarf") + set(CPPTRACE_BACKEND_OPTION "CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF=ON") +else () + set(CPPTRACE_BACKEND_OPTION "CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE=ON") +endif () + +FetchContent_MakeAvailableWithArgs(cpptrace + ${CPPTRACE_BACKEND_OPTION} +) diff --git a/cmake/glog.cmake b/cmake/glog.cmake index 4a29a589755..5e9c12687e3 100644 --- a/cmake/glog.cmake +++ b/cmake/glog.cmake @@ -28,5 +28,4 @@ FetchContent_MakeAvailableWithArgs(glog WITH_GFLAGS=OFF WITH_GTEST=OFF BUILD_SHARED_LIBS=OFF - WITH_UNWIND=${ENABLE_UNWIND} ) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index cd023a726c7..cce10cbf982 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -34,6 +34,7 @@ function(FetchContent_MakeAvailableWithArgs dep) parse_var(${arg} key value) set(${key}_OLD ${${key}}) set(${key} ${value} CACHE INTERNAL "") + message("In ${dep}: ${key} set to ${value}") endforeach() add_subdirectory(${${dep}_SOURCE_DIR} ${${dep}_BINARY_DIR} EXCLUDE_FROM_ALL) diff --git a/licenses/LICENSE-cpptrace.txt b/licenses/LICENSE-cpptrace.txt new file mode 100644 index 00000000000..299bf1fac8c --- /dev/null +++ b/licenses/LICENSE-cpptrace.txt @@ -0,0 +1,18 @@ +The MIT License (MIT) + +Copyright (c) 2023-2024 Jeremy Rifkin + +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. diff --git a/src/cli/signal_util.h b/src/cli/signal_util.h index cb5abc67371..d6f02e614aa 100644 --- a/src/cli/signal_util.h +++ b/src/cli/signal_util.h @@ -24,39 +24,19 @@ #include #include +#include #include #include #include "version_util.h" -namespace google { -bool Symbolize(void *pc, char *out, size_t out_size); -} // namespace google - extern "C" inline void SegvHandler(int sig, siginfo_t *info, void *secret) { - void *trace[100]; - - LOG(ERROR) << "======= Ooops! kvrocks " << PrintVersion << " got signal: " << strsignal(sig) << " (" << sig - << ") ======="; - int trace_size = backtrace(trace, sizeof(trace) / sizeof(void *)); - char **messages = backtrace_symbols(trace, trace_size); - - size_t max_msg_len = 0; - for (int i = 1; i < trace_size; ++i) { - auto msg_len = strlen(messages[i]); - if (msg_len > max_msg_len) { - max_msg_len = msg_len; - } - } - - for (int i = 1; i < trace_size; ++i) { - char func_info[1024] = {}; - if (google::Symbolize(trace[i], func_info, sizeof(func_info) - 1)) { - LOG(ERROR) << std::left << std::setw(static_cast(max_msg_len)) << messages[i] << " " << func_info; - } else { - LOG(ERROR) << messages[i]; - } - } + LOG(ERROR) << "Ooops! Apache Kvrocks " << PrintVersion << " got signal: " << strsignal(sig) << " (" << sig << ")"; + auto trace = cpptrace::generate_trace(); + trace.print(LOG(ERROR)); + LOG(ERROR) + << "It would be greatly appreciated if you could submit this crash to https://github.com/apache/kvrocks/issues " + "along with the stacktrace above, logs and any relevant information."; struct sigaction act; /* Make sure we exit with the right signal at the end. So for instance