diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6c01a58..3736e88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,8 @@ on: push: pull_request: +# TODO: Test statically linked + jobs: test-linux: runs-on: ubuntu-22.04 @@ -41,12 +43,12 @@ jobs: -D${{matrix.symbols}}=On \ -D${{matrix.demangle}}=On \ -DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \ - -DCPPTRACE_BUILD_TEST=On + -DCPPTRACE_BUILD_TEST=On \ + -DBUILD_SHARED_LIBS=On make - name: test working-directory: build run: | - #readelf --debug-dump=info test | grep foo ./test | python3 ../test/test.py "${{matrix.compiler}}" test-windows: runs-on: windows-2019 @@ -86,7 +88,8 @@ jobs: -D${{matrix.unwind}}=On ` -D${{matrix.symbols}}=On ` -D${{matrix.demangle}}=On ` - -DCPPTRACE_BUILD_TEST=On + -DCPPTRACE_BUILD_TEST=On ` + -DBUILD_SHARED_LIBS=On msbuild .\cpptrace.sln - name: test working-directory: build @@ -116,7 +119,8 @@ jobs: -DCMAKE_CXX_STANDARD=${{matrix.std}} \ -DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \ ${{matrix.config}} \ - -DCPPTRACE_BUILD_TEST=On + -DCPPTRACE_BUILD_TEST=On \ + -DBUILD_SHARED_LIBS=On make - name: test working-directory: build @@ -146,7 +150,8 @@ jobs: -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` -DCMAKE_CXX_STANDARD=${{matrix.std}} ` ${{matrix.config}} ` - -DCPPTRACE_BUILD_TEST=On + -DCPPTRACE_BUILD_TEST=On ` + -DBUILD_SHARED_LIBS=On msbuild .\cpptrace.sln - name: test working-directory: build diff --git a/.gitignore b/.gitignore index 71a5bcc..8750b75 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build build2 a.out test/build +repro*/ diff --git a/README.md b/README.md index 0fd165e..e2abead 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Make stack traces simple for once. Support for MacOS and cygwin/mingw will be added soon. -*Some day C++23's `` will be ubiquitous* +*Some day C++23's `` will be ubiquitous, and maybe one day the msvc implementation will be acceptable* ## Table of contents diff --git a/src/cpptrace.cpp b/src/cpptrace.cpp index 71b1cff..66bb704 100644 --- a/src/cpptrace.cpp +++ b/src/cpptrace.cpp @@ -5,12 +5,12 @@ #include #include -#ifndef CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE +#if !(defined(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE) || defined(CPPTRACE_FULL_TRACE_WITH_STACKTRACE)) -#include "symbols/libcpp_symbols.hpp" -#include "unwind/libcpp_unwind.hpp" -#include "demangle/libcpp_demangle.hpp" -#include "platform/libcpp_common.hpp" +#include "symbols/cpptrace_symbols.hpp" +#include "unwind/cpptrace_unwind.hpp" +#include "demangle/cpptrace_demangle.hpp" +#include "platform/cpptrace_common.hpp" namespace cpptrace { CPPTRACE_FORCE_NO_INLINE @@ -31,8 +31,8 @@ namespace cpptrace { // full trace -#include "full/libcpp_full_trace.hpp" -#include "demangle/libcpp_demangle.hpp" +#include "full/cpptrace_full_trace.hpp" +#include "demangle/cpptrace_demangle.hpp" namespace cpptrace { CPPTRACE_FORCE_NO_INLINE diff --git a/src/demangle/libcpp_demangle.hpp b/src/demangle/cpptrace_demangle.hpp similarity index 73% rename from src/demangle/libcpp_demangle.hpp rename to src/demangle/cpptrace_demangle.hpp index efb90cc..358aee4 100644 --- a/src/demangle/libcpp_demangle.hpp +++ b/src/demangle/cpptrace_demangle.hpp @@ -1,5 +1,5 @@ -#ifndef LIBCPP_DEMANGLE_HPP -#define LIBCPP_DEMANGLE_HPP +#ifndef CPPTRACE_DEMANGLE_HPP +#define CPPTRACE_DEMANGLE_HPP #include diff --git a/src/demangle/demangle_with_cxxabi.cpp b/src/demangle/demangle_with_cxxabi.cpp index 7a05541..b0ce423 100644 --- a/src/demangle/demangle_with_cxxabi.cpp +++ b/src/demangle/demangle_with_cxxabi.cpp @@ -1,7 +1,7 @@ #ifdef CPPTRACE_DEMANGLE_WITH_CXXABI #include -#include "libcpp_demangle.hpp" +#include "cpptrace_demangle.hpp" #include diff --git a/src/demangle/demangle_with_nothing.cpp b/src/demangle/demangle_with_nothing.cpp index 313f2a6..e86acf4 100644 --- a/src/demangle/demangle_with_nothing.cpp +++ b/src/demangle/demangle_with_nothing.cpp @@ -1,7 +1,7 @@ #ifdef CPPTRACE_DEMANGLE_WITH_NOTHING #include -#include "libcpp_demangle.hpp" +#include "cpptrace_demangle.hpp" #include #include diff --git a/src/full/libcpp_full_trace.hpp b/src/full/cpptrace_full_trace.hpp similarity index 68% rename from src/full/libcpp_full_trace.hpp rename to src/full/cpptrace_full_trace.hpp index b5c8a9d..85d14a9 100644 --- a/src/full/libcpp_full_trace.hpp +++ b/src/full/cpptrace_full_trace.hpp @@ -1,8 +1,8 @@ -#ifndef LIBCPP_FULL_TRACE_HPP -#define LIBCPP_FULL_TRACE_HPP +#ifndef CPPTRACE_FULL_TRACE_HPP +#define CPPTRACE_FULL_TRACE_HPP #include -#include "../platform/libcpp_common.hpp" +#include "../platform/cpptrace_common.hpp" #include #include diff --git a/src/full/full_trace_with_libbacktrace.cpp b/src/full/full_trace_with_libbacktrace.cpp index 00e283d..e542cbb 100644 --- a/src/full/full_trace_with_libbacktrace.cpp +++ b/src/full/full_trace_with_libbacktrace.cpp @@ -1,9 +1,9 @@ #ifdef CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE #include -#include "libcpp_full_trace.hpp" -#include "../platform/libcpp_program_name.hpp" -#include "../platform/libcpp_common.hpp" +#include "cpptrace_full_trace.hpp" +#include "../platform/cpptrace_program_name.hpp" +#include "../platform/cpptrace_common.hpp" #include @@ -50,7 +50,7 @@ namespace cpptrace { static backtrace_state* state = nullptr; static bool called = false; if(!called) { - state = backtrace_create_state(program_name().c_str(), true, error_callback, nullptr); + state = backtrace_create_state(program_name(), true, error_callback, nullptr); called = true; } return state; diff --git a/src/full/full_trace_with_stacktrace.cpp b/src/full/full_trace_with_stacktrace.cpp index 2b818ab..fc18775 100644 --- a/src/full/full_trace_with_stacktrace.cpp +++ b/src/full/full_trace_with_stacktrace.cpp @@ -1,8 +1,8 @@ #ifdef CPPTRACE_FULL_TRACE_WITH_STACKTRACE #include -#include "libcpp_full_trace.hpp" -#include "../platform/libcpp_common.hpp" +#include "cpptrace_full_trace.hpp" +#include "../platform/cpptrace_common.hpp" #include #include diff --git a/src/platform/libcpp_common.hpp b/src/platform/cpptrace_common.hpp similarity index 72% rename from src/platform/libcpp_common.hpp rename to src/platform/cpptrace_common.hpp index 61e57a1..8d058e0 100644 --- a/src/platform/libcpp_common.hpp +++ b/src/platform/cpptrace_common.hpp @@ -1,5 +1,5 @@ -#ifndef LIBCPP_COMMON_HPP -#define LIBCPP_COMMON_HPP +#ifndef CPPTRACE_COMMON_HPP +#define CPPTRACE_COMMON_HPP #ifdef _MSC_VER #define CPPTRACE_FORCE_NO_INLINE __declspec(noinline) diff --git a/src/platform/cpptrace_program_name.hpp b/src/platform/cpptrace_program_name.hpp new file mode 100644 index 0000000..224f897 --- /dev/null +++ b/src/platform/cpptrace_program_name.hpp @@ -0,0 +1,51 @@ +#ifndef CPPTRACE_PROGRAM_NAME_HPP +#define CPPTRACE_PROGRAM_NAME_HPP + +#include + +#ifdef _WIN32 +#include + +namespace cpptrace { + namespace detail { + inline std::string program_name() { + char buffer[MAX_PATH + 1]; + int res = GetModuleFileNameA(nullptr, buffer, MAX_PATH); + if(res) { + return buffer; + } else { + return ""; + } + } + } +} + +#else +#include +#include + +namespace cpptrace { + namespace detail { + inline const char* program_name() { + static std::string name; + static bool did_init = false; + static bool valid = false; + if(!did_init) { + did_init = true; + char buffer[PATH_MAX + 1]; + ssize_t s = readlink("/proc/self/exe", buffer, PATH_MAX); + if(s == -1) { + return nullptr; + } + buffer[s] = 0; + name = buffer; + valid = true; + } + return valid ? name.c_str() : nullptr; + } + } +} + +#endif + +#endif diff --git a/src/platform/libcpp_program_name.hpp b/src/platform/libcpp_program_name.hpp deleted file mode 100644 index 90019df..0000000 --- a/src/platform/libcpp_program_name.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef LIBCPP_PROGRAM_NAME_HPP -#define LIBCPP_PROGRAM_NAME_HPP - -#include - -#ifdef _WIN32 -#include - -namespace cpptrace { - namespace detail { - inline std::string program_name() { - char buffer[MAX_PATH + 1]; - int res = GetModuleFileNameA(nullptr, buffer, MAX_PATH); - if(res) { - return buffer; - } else { - return ""; - } - } - } -} - -#else - -namespace cpptrace { - namespace detail { - inline std::string program_name() { - return ""; - } - } -} - -#endif - -#endif diff --git a/src/symbols/libcpp_symbols.hpp b/src/symbols/cpptrace_symbols.hpp similarity index 86% rename from src/symbols/libcpp_symbols.hpp rename to src/symbols/cpptrace_symbols.hpp index 426534c..4115a9d 100644 --- a/src/symbols/libcpp_symbols.hpp +++ b/src/symbols/cpptrace_symbols.hpp @@ -1,5 +1,5 @@ -#ifndef LIBCPP_SYMBOLS_HPP -#define LIBCPP_SYMBOLS_HPP +#ifndef CPPTRACE_SYMBOLS_HPP +#define CPPTRACE_SYMBOLS_HPP #include diff --git a/src/symbols/symbols_with_dbghelp.cpp b/src/symbols/symbols_with_dbghelp.cpp index e6d5cfc..29ce5fd 100644 --- a/src/symbols/symbols_with_dbghelp.cpp +++ b/src/symbols/symbols_with_dbghelp.cpp @@ -1,8 +1,8 @@ #ifdef CPPTRACE_GET_SYMBOLS_WITH_DBGHELP #include -#include "libcpp_symbols.hpp" -#include "../platform/libcpp_program_name.hpp" +#include "cpptrace_symbols.hpp" +#include "../platform/cpptrace_program_name.hpp" #include #include diff --git a/src/symbols/symbols_with_libbacktrace.cpp b/src/symbols/symbols_with_libbacktrace.cpp index 8c90c03..80efdac 100644 --- a/src/symbols/symbols_with_libbacktrace.cpp +++ b/src/symbols/symbols_with_libbacktrace.cpp @@ -1,8 +1,8 @@ #ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE #include -#include "libcpp_symbols.hpp" -#include "../platform/libcpp_program_name.hpp" +#include "cpptrace_symbols.hpp" +#include "../platform/cpptrace_program_name.hpp" #include #include @@ -18,7 +18,7 @@ namespace cpptrace { int full_callback(void* data, uintptr_t address, const char* file, int line, const char* symbol) { stacktrace_frame& frame = *static_cast(data); if(line == 0) { - fprintf(stderr, "Getting bad data for some reason\n"); + ///fprintf(stderr, "Getting bad data for some reason\n"); // TODO: Eliminate } frame.address = address; frame.line = line; @@ -37,7 +37,7 @@ namespace cpptrace { void error_callback(void* data, const char* msg, int errnum) { // nothing at the moment - fprintf(stderr, "Backtrace error %s %d %p\n", msg, errnum, data); + ///fprintf(stderr, "Backtrace error %s %d %p\n", msg, errnum, data); // TODO: Eliminate } backtrace_state* get_backtrace_state() { @@ -45,7 +45,7 @@ namespace cpptrace { static backtrace_state* state = nullptr; static bool called = false; if(!called) { - state = backtrace_create_state(program_name().c_str(), true, error_callback, nullptr); + state = backtrace_create_state(program_name(), true, error_callback, nullptr); called = true; } return state; @@ -56,13 +56,15 @@ namespace cpptrace { stacktrace_frame resolve_frame(void* addr) { stacktrace_frame frame; frame.col = -1; - if(!backtrace_pcinfo( + backtrace_pcinfo( get_backtrace_state(), reinterpret_cast(addr), full_callback, error_callback, &frame - )) { + ); + if(frame.symbol.empty()) { + // fallback, try to at least recover the symbol name with backtrace_syminfo backtrace_syminfo( get_backtrace_state(), reinterpret_cast(addr), diff --git a/src/symbols/symbols_with_nothing.cpp b/src/symbols/symbols_with_nothing.cpp index 8ddccac..b618863 100644 --- a/src/symbols/symbols_with_nothing.cpp +++ b/src/symbols/symbols_with_nothing.cpp @@ -1,8 +1,8 @@ #ifdef CPPTRACE_GET_SYMBOLS_WITH_NOTHING #include -#include "libcpp_symbols.hpp" -#include "../platform/libcpp_program_name.hpp" +#include "cpptrace_symbols.hpp" +#include "../platform/cpptrace_program_name.hpp" #include diff --git a/src/unwind/libcpp_unwind.hpp b/src/unwind/cpptrace_unwind.hpp similarity index 79% rename from src/unwind/libcpp_unwind.hpp rename to src/unwind/cpptrace_unwind.hpp index dcf209a..8e351c1 100644 --- a/src/unwind/libcpp_unwind.hpp +++ b/src/unwind/cpptrace_unwind.hpp @@ -1,8 +1,8 @@ -#ifndef LIBCPP_UNWIND_HPP -#define LIBCPP_UNWIND_HPP +#ifndef CPPTRACE_UNWIND_HPP +#define CPPTRACE_UNWIND_HPP #include -#include "../platform/libcpp_common.hpp" +#include "../platform/cpptrace_common.hpp" #include diff --git a/src/unwind/unwind_with_execinfo.cpp b/src/unwind/unwind_with_execinfo.cpp index 5d8cd82..7be1f3e 100644 --- a/src/unwind/unwind_with_execinfo.cpp +++ b/src/unwind/unwind_with_execinfo.cpp @@ -1,8 +1,8 @@ #ifdef CPPTRACE_UNWIND_WITH_EXECINFO #include -#include "libcpp_unwind.hpp" -#include "../platform/libcpp_common.hpp" +#include "cpptrace_unwind.hpp" +#include "../platform/cpptrace_common.hpp" #include #include diff --git a/src/unwind/unwind_with_nothing.cpp b/src/unwind/unwind_with_nothing.cpp index 1146189..8462e9d 100644 --- a/src/unwind/unwind_with_nothing.cpp +++ b/src/unwind/unwind_with_nothing.cpp @@ -1,7 +1,7 @@ #ifdef CPPTRACE_UNWIND_WITH_NOTHING #include -#include "libcpp_unwind.hpp" +#include "cpptrace_unwind.hpp" #include diff --git a/src/unwind/unwind_with_winapi.cpp b/src/unwind/unwind_with_winapi.cpp index 30f833f..15f0fc4 100644 --- a/src/unwind/unwind_with_winapi.cpp +++ b/src/unwind/unwind_with_winapi.cpp @@ -1,8 +1,8 @@ #ifdef CPPTRACE_UNWIND_WITH_WINAPI #include -#include "libcpp_unwind.hpp" -#include "../platform/libcpp_common.hpp" +#include "cpptrace_unwind.hpp" +#include "../platform/cpptrace_common.hpp" #include diff --git a/test/test.py b/test/test.py index e65ba6f..5626104 100644 --- a/test/test.py +++ b/test/test.py @@ -22,6 +22,8 @@ def main(): output = sys.stdin.read() + print(output) # for debug reasons + if output.strip() == "": print(f"Error: No output from test", file=sys.stderr) sys.exit(1) @@ -47,8 +49,11 @@ def main(): break if errored: - print("Test output:", file=sys.stderr) - print(raw_output, file=sys.stderr) + #print("Test output:", file=sys.stderr) + #print(raw_output, file=sys.stderr) + print("Test failed") sys.exit(1) + else: + print("Test passed") main()