diff --git a/Dockerfile.dropshell-build b/Dockerfile.dropshell-build index db0b907..b251629 100644 --- a/Dockerfile.dropshell-build +++ b/Dockerfile.dropshell-build @@ -17,10 +17,17 @@ RUN apk add --no-cache \ mold \ zlib-static \ ccache \ + pkgconf \ + pkgconfig \ + libunwind \ libunwind-dev \ - libdwarf-dev \ - binutils \ - elfutils-dev + libunwind-static \ + libunwind-dbg \ + zlib-dev \ + zlib-static \ + xz-dev \ + xz-static \ + xz-libs #RUN apk add --no-cache --update --repository=https://dl-cdn.alpinelinux.org/alpine/v3.16/main/ libexecinfo-dev @@ -41,9 +48,6 @@ RUN --mount=type=cache,target=/build \ -DZLIB_BUILD_SHARED=OFF \ -DZLIB_BUILD_STATIC=ON \ -DBUILD_SHARED_LIBS=OFF \ - -DCPPTRACE_UNWIND_WITH_UNWIND=ON \ - -DCPPTRACE_GET_SYMBOLS_WITH_LIBDWARF=ON \ - -DCPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE=ON \ -DPROJECT_NAME="${PROJECT}" \ -DCMAKE_STRIP=OFF \ -DIGNORE_DYNAMIC_LOADING=ON \ diff --git a/ipdemo/CMakeLists.txt b/ipdemo/CMakeLists.txt index 836968c..570139f 100644 --- a/ipdemo/CMakeLists.txt +++ b/ipdemo/CMakeLists.txt @@ -5,11 +5,14 @@ execute_process( OUTPUT_STRIP_TRAILING_WHITESPACE ) -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.14) if(NOT DEFINED PROJECT_NAME) message(FATAL_ERROR "PROJECT_NAME is not defined. Pass it via -DPROJECT_NAME=") endif() +# Include required modules +include(FetchContent) + project(${PROJECT_NAME} VERSION ${PROJECT_VERSION} LANGUAGES CXX) set(PROJECT_EXE_NAME ${PROJECT_NAME}) @@ -19,16 +22,16 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE) set(CMAKE_POSITION_INDEPENDENT_CODE OFF) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static -rdynamic") set(ZLIB_USE_STATIC_LIBS "ON") set(CMAKE_CXX_STANDARD 23) set(CMAKE_C_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Set default build type to Release if not specified +# Set default build type to Debug if not specified if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build (Debug or Release)" FORCE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build (Debug or Release)" FORCE) endif() # Configure build-specific compiler flags @@ -69,24 +72,6 @@ target_include_directories(${PROJECT_EXE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/autogen ) - -# Configure libassert -include(FetchContent) -FetchContent_Declare( - libassert - GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert.git - GIT_TAG v2.1.5 -) -FetchContent_MakeAvailable(libassert) - -# Add cpptrace -FetchContent_Declare( - cpptrace - GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git - GIT_TAG v0.8.3 -) -FetchContent_MakeAvailable(cpptrace) - # Add nlohmann/json FetchContent_Declare( nlohmann_json @@ -95,17 +80,31 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(nlohmann_json) -# Link libraries -target_link_libraries(${PROJECT_EXE_NAME} PRIVATE - libassert::assert - cpptrace::cpptrace - nlohmann_json::nlohmann_json +# Find required libraries using pkg-config +find_package(PkgConfig REQUIRED) +pkg_check_modules(LIBUNWIND REQUIRED IMPORTED_TARGET libunwind) + +# Additional required libraries for static linking +set(EXTRA_LIBS + ${LIBUNWIND_LIBRARIES} + -lunwind + -lunwind-x86_64 + -llzma + -lz + -ldl ) -# Add execinfo to linker flags -set_target_properties(${PROJECT_EXE_NAME} PROPERTIES - LINK_FLAGS "-static" +# Link libraries +target_link_libraries(${PROJECT_EXE_NAME} PRIVATE + nlohmann_json::nlohmann_json + ${EXTRA_LIBS} ) +# Set static linking flags +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +set(BUILD_SHARED_LIBS OFF) +set(CMAKE_POSITION_INDEPENDENT_CODE OFF) + # Add musl's backtrace headers include_directories(/usr/include/musl) \ No newline at end of file diff --git a/ipdemo/src/assert.hpp b/ipdemo/src/assert.hpp new file mode 100644 index 0000000..ea73843 --- /dev/null +++ b/ipdemo/src/assert.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +[[noreturn]] void print_stacktrace() { + unw_cursor_t cursor; + unw_context_t context; + unw_word_t offset, pc; + char sym[256]; + char *name = sym; + int status; + + // Initialize cursor to current frame + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + std::cerr << "Stack trace (most recent call first):\n"; + + // Walk up the stack + while (unw_step(&cursor) > 0) { + unw_get_reg(&cursor, UNW_REG_IP, &pc); + if (pc == 0) { + break; + } + + // Get symbol name + if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) { + // Demangle the C++ name + int status; + size_t length = sizeof(sym); + name = abi::__cxa_demangle(sym, nullptr, &length, &status); + if (name == nullptr) { + name = sym; + } + std::cerr << " 0x" << std::hex << pc << ": " << name << " + 0x" << offset << "\n"; + if (name != sym) { + free(name); + } + } else { + std::cerr << " 0x" << std::hex << pc << ": [unknown]\n"; + } + } +} + +[[noreturn]] void assert_failed( + bool condition, + std::string_view message, + std::source_location location = std::source_location::current() +) { + if (!condition) { + std::cerr << "Assertion failed at " << location.file_name() << ":" << location.line() << ": " + << location.function_name() << "(): " << message << "\n"; + print_stacktrace(); + std::abort(); + } +} + +#define ASSERT(condition, message) assert_failed(condition, message, std::source_location::current()) diff --git a/ipdemo/src/main.cpp b/ipdemo/src/main.cpp index c4d2a40..a661efe 100644 --- a/ipdemo/src/main.cpp +++ b/ipdemo/src/main.cpp @@ -1,13 +1,12 @@ #include - #include -#include #include "httplib.hpp" #include "version.hpp" +#include "assert.hpp" void crashy() { - ASSERT(false,"SUCCESS!"); + ASSERT(false, "SUCCESS!"); } int main() {