From 2545e6c2e592732f5c8df5d6d6c8efcb6ae9fe90 Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Tue, 12 Sep 2023 01:16:18 -0400 Subject: [PATCH] Use .dSYM files on macos. Should fix test cases. --- CMakeLists.txt | 17 +++++++++++++++++ README.md | 11 +++++++++++ src/platform/common.hpp | 22 ++++++++++++++++++---- src/symbols/symbols_with_libdwarf.cpp | 21 ++++++++++++++++++--- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 860a5b4..b464b12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -452,6 +452,7 @@ endif() if(CPPTRACE_BUILD_TEST) add_executable(test test/test.cpp) + target_compile_features(test PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert) target_link_libraries(test PRIVATE cpptrace) # Clang has been fast to adopt dwarf 5, other tools (e.g. addr2line from binutils) have not check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4) @@ -461,10 +462,18 @@ if(CPPTRACE_BUILD_TEST) if(CPPTRACE_BUILD_TEST_RDYNAMIC) set_property(TARGET test PROPERTY ENABLE_EXPORTS ON) endif() + if(APPLE) # TODO: Temporary + add_custom_command( + TARGET test + POST_BUILD + COMMAND dsymutil $ + ) + endif() endif() if(CPPTRACE_BUILD_DEMO) add_executable(demo test/demo.cpp) + target_compile_features(demo PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert) target_link_libraries(demo PRIVATE cpptrace) # Clang has been fast to adopt dwarf 5, other tools (e.g. addr2line from binutils) have not check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4) @@ -474,6 +483,13 @@ if(CPPTRACE_BUILD_DEMO) if(CPPTRACE_BUILD_TEST_RDYNAMIC) set_property(TARGET demo PROPERTY ENABLE_EXPORTS ON) endif() + if(APPLE) # TODO: Temporary + add_custom_command( + TARGET demo + POST_BUILD + COMMAND dsymutil $ + ) + endif() endif() if(CPPTRACE_BUILD_SPEEDTEST) @@ -504,6 +520,7 @@ if(CPPTRACE_BUILD_SPEEDTEST) FetchContent_MakeAvailable(googletest) add_executable(speedtest test/speedtest.cpp) + target_compile_features(speedtest PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert) target_link_libraries( speedtest PRIVATE diff --git a/README.md b/README.md index e2d84b9..a0db8ff 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,14 @@ if(WIN32) # Copy the .dll on windows $ ) endif() + +if(APPLE) # Create a .dSYM file on apple. Currently required, but hopefully not for long + add_custom_command( + TARGET your_target + POST_BUILD + COMMAND dsymutil $ + ) +endif() ``` It's as easy as that. Cpptrace will automatically configure itself for your system. @@ -154,6 +162,9 @@ be used to get raw frame information for custom use. **Note:** Debug info (`-g`) is generally required for good trace information. Some back-ends read symbols from dynamic export information which may require `-rdynamic` or manually marking symbols for exporting. +**Note:** Currently on Mac .dSYM files are required, which can be generated with `dsymutil yourbinary`. A cmake snippet +for generating these is included above. + ```cpp namespace cpptrace { struct stacktrace_frame { diff --git a/src/platform/common.hpp b/src/platform/common.hpp index fa678b8..58efde0 100644 --- a/src/platform/common.hpp +++ b/src/platform/common.hpp @@ -62,6 +62,8 @@ #if IS_WINDOWS #include +#else + #include #endif // Lightweight std::source_location. @@ -268,10 +270,6 @@ class file_error : std::exception { } }; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - struct nullopt_t {}; static constexpr nullopt_t nullopt; @@ -420,4 +418,20 @@ public: } }; +// shamelessly stolen from stackoverflow +CPPTRACE_MAYBE_UNUSED +static bool directory_exists(const std::string& path) { + #if IS_WINDOWS + DWORD dwAttrib = GetFileAttributesA(path.c_str()); + return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY); + #else + struct stat sb; + return stat(path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode); + #endif +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #endif diff --git a/src/symbols/symbols_with_libdwarf.cpp b/src/symbols/symbols_with_libdwarf.cpp index 41df85a..1812791 100644 --- a/src/symbols/symbols_with_libdwarf.cpp +++ b/src/symbols/symbols_with_libdwarf.cpp @@ -2,7 +2,9 @@ #include #include "symbols.hpp" +#include "../platform/common.hpp" #include "../platform/program_name.hpp" +#include "../platform/object.hpp" #include #include @@ -16,7 +18,9 @@ #include #include -#include "../platform/object.hpp" +#if IS_APPLE + #include +#endif // some stuff is based on https://github.com/davea42/libdwarf-addr2line/blob/master/addr2line.c, mainly line handling // then much expanded for symbols and efficiency @@ -939,17 +943,28 @@ namespace cpptrace { frame.filename = frame_info.obj_path; frame.symbol = frame_info.symbol; frame.address = frame_info.raw_address; + std::string obj_path = frame_info.obj_path; + #if IS_APPLE + //std::string obj_path = frame_info.obj_path; + //char* dir = dirname(obj_path.data()); + //std::string dsym = + if(directory_exists(obj_path + ".dSYM")) { + std::string obj_path_copy = frame_info.obj_path; + std::string base = basename(const_cast(obj_path_copy.data())); + obj_path += ".dSYM/Contents/Resources/DWARF/" + base; + } + #endif if(trace_dwarf) { fprintf( stderr, "%s %08lx %s\n", - frame_info.obj_path.c_str(), + obj_path.c_str(), frame_info.obj_address, frame_info.symbol.c_str() ); } lookup_pc( - frame_info.obj_path.c_str(), + obj_path.c_str(), frame_info.obj_address, frame );