Build work (#1)

This commit is contained in:
Jeremy Rifkin 2023-07-01 22:14:05 -04:00 committed by GitHub
parent b3474b50c3
commit 99a54e3597
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 216 additions and 74 deletions

View File

@ -1,34 +1,70 @@
name: build c++20
name: build
on:
push:
pull_request:
jobs:
build-gcc:
build-linux:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-10, clang++-14]
target: [Debug]
std: [11, 20]
unwind: [
LIBCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
LIBCPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
symbols: [
LIBCPPTRACE_UNWIND_WITH_EXECINFO,
LIBCPPTRACE_UNWIND_WITH_NOTHING,
]
demangle: [
LIBCPPTRACE_DEMANGLE_WITH_CXXABI,
LIBCPPTRACE_DEMANGLE_WITH_NOTHING,
]
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-10 g++-10
run: sudo apt install gcc-10 g++-10 libgcc-10-dev
- name: build
run: |
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-10
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-D${{matrix.unwind}}=On \
-D${{matrix.symbols}}=On \
-D${{matrix.demangle}}=On \
-DLIBCPP_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h
make
build-clang:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: build
run: |
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=clang++-14
make
build-msvc:
build-windows:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
compiler: [cl, clang++]
target: [Debug]
std: [11, 20]
unwind: [
# LIBCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE
LIBCPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
symbols: [
LIBCPPTRACE_UNWIND_WITH_WINAPI,
LIBCPPTRACE_UNWIND_WITH_NOTHING,
]
demangle: [
# LIBCPPTRACE_DEMANGLE_WITH_CXXABI,
LIBCPPTRACE_DEMANGLE_WITH_NOTHING,
]
exclude:
- demangle: LIBCPPTRACE_DEMANGLE_WITH_CXXABI
compiler: cl
steps:
- uses: actions/checkout@v2
- name: Enable Developer Command Prompt
@ -37,5 +73,61 @@ jobs:
run: |
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=cl
cmake .. `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
-D${{matrix.unwind}}=On `
-D${{matrix.symbols}}=On `
-D${{matrix.demangle}}=On
msbuild .\libcpptrace.sln
build-linux-full-or-auto:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-10, clang++-14]
target: [Debug]
std: [11, 20]
config: ["-DLIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""]
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-10 g++-10 libgcc-10-dev
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-DLIBCPP_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
${{matrix.config}}
make
build-windows-full-or-auto:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
compiler: [cl, clang++]
target: [Debug]
std: [11, 20]
config: [""]
exclude:
- config: -DLIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On # TODO
steps:
- uses: actions/checkout@v2
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1.10.0
- name: build
run: |
mkdir -p build
cd build
cmake .. `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
${{matrix.config}}
msbuild .\libcpptrace.sln

View File

@ -18,7 +18,6 @@ include(GNUInstallDirs)
include(CheckCXXSourceCompiles)
file(GLOB_RECURSE sources src/*.cpp)
#message(STATUS "Sources" ${sources})
add_library(cpptrace ${sources} include/cpptrace/cpptrace.hpp)
target_include_directories(
@ -48,15 +47,6 @@ target_compile_options(
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX /permissive->
)
function(check_support var source includes libraries definitions)
set(CMAKE_REQUIRED_INCLUDES "${includes}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_REQUIRED_LIBRARIES "${libraries}")
set(CMAKE_REQUIRED_DEFINITIONS "${definitions}")
check_cxx_source_compiles("#include \"${source}\"" ${var})
set(${var} ${${var}} PARENT_SCOPE)
endfunction()
option(LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE "" OFF)
option(LIBCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE "" OFF)
@ -72,6 +62,36 @@ option(LIBCPPTRACE_UNWIND_WITH_NOTHING "" OFF)
option(LIBCPPTRACE_DEMANGLE_WITH_CXXABI "" OFF)
option(LIBCPPTRACE_DEMANGLE_WITH_NOTHING "" OFF)
set(LIBCPP_BACKTRACE_PATH "" CACHE STRING "Path to backtrace.h, if the compiler doesn't already know it. Check /usr/lib/gcc/x86_64-linux-gnu/*/include.")
if(NOT "${LIBCPP_BACKTRACE_PATH}" STREQUAL "")
# quotes used over <> because of a macro substitution issue where
# </usr/lib/gcc/x86_64-linux-gnu/12/include/backtrace.h>
# is expanded to
# </usr/lib/gcc/x86_64-1-gnu/12/include/backtrace.h>
string(CONCAT LIBCPP_BACKTRACE_PATH "\"" ${LIBCPP_BACKTRACE_PATH})
string(CONCAT LIBCPP_BACKTRACE_PATH ${LIBCPP_BACKTRACE_PATH} "\"")
#message(STATUS ${LIBCPP_BACKTRACE_PATH})
string(CONCAT LIBCPP_BACKTRACE_PATH_DEFINITION "-DLIBCPP_BACKTRACE_PATH=" ${LIBCPP_BACKTRACE_PATH})
#message(STATUS ${LIBCPP_BACKTRACE_PATH_DEFINITION})
else()
set(LIBCPP_BACKTRACE_PATH_DEFINITION "")
endif()
function(check_support var source includes libraries definitions)
set(CMAKE_REQUIRED_INCLUDES "${includes}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_REQUIRED_LIBRARIES "${libraries}")
set(CMAKE_REQUIRED_DEFINITIONS "${definitions}")
string(CONCAT full_source "#include \"${source}\"" ${nonce})
check_cxx_source_compiles(${full_source} ${var})
set(${var} ${${var}} PARENT_SCOPE)
endfunction()
check_support(HAS_EXECINFO has_execinfo.cpp "" "" "")
check_support(HAS_BACKTRACE has_backtrace.cpp "" "backtrace" "${LIBCPP_BACKTRACE_PATH_DEFINITION}")
check_support(HAS_CXXABI has_cxxabi.cpp "" "" "")
# =============================================== Autoconfig full dump ===============================================
# If nothing is specified, attempt to use libbacktrace's full dump
if(
@ -85,8 +105,6 @@ if(
)
)
# Attempt to auto-config
check_support(HAS_BACKTRACE has_backtrace.cpp "" "backtrace" "")
if(HAS_BACKTRACE)
set(LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE On)
message(STATUS "Cpptrace auto config: Using libbacktrace for the full trace")
@ -105,14 +123,12 @@ if(
)
# Attempt to auto-config
if(UNIX)
check_support(HAS_EXECINFO has_execinfo.cpp "" "" "")
if(HAS_EXECINFO)
set(LIBCPPTRACE_UNWIND_WITH_EXECINFO On)
message(STATUS "Cpptrace auto config: Using execinfo.h for unwinding")
else()
set(LIBCPPTRACE_UNWIND_WITH_NOTHING On)
message(WARNING "Cpptrace auto config: <execinfo.h> doesn't seem to be supported, stack tracing will not work.")
message(FATAL_ERROR "Cpptrace auto config: <execinfo.h> doesn't seem to be supported, stack tracing will not work. To compile anyway set LIBCPPTRACE_UNWIND_WITH_NOTHING.")
endif()
elseif(WIN32)
set(LIBCPPTRACE_UNWIND_WITH_WINAPI On)
@ -133,13 +149,11 @@ if(
)
# Attempt to auto-config
if(UNIX)
check_support(HAS_EXECINFO has_execinfo.cpp "" "" "")
if(HAS_EXECINFO)
if(HAS_BACKTRACE)
set(LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE On)
message(STATUS "Cpptrace auto config: Using libbacktrace for symbols")
else()
message(WARNING "Cpptrace auto config: No symbol back end could be automatically configured")
message(FATAL_ERROR "Cpptrace auto config: No symbol back end could be automatically configured. To compile anyway set LIBCPPTRACE_GET_SYMBOLS_WITH_NOTHING.")
endif()
elseif(WIN32)
#set(LIBCPPTRACE_UNWIND_WITH_WINAPI On)
@ -157,7 +171,6 @@ if(
LIBCPPTRACE_DEMANGLE_WITH_NOTHING
)
)
check_support(HAS_CXXABI has_cxxabi.cpp "" "" "")
if(HAS_CXXABI)
set(LIBCPPTRACE_DEMANGLE_WITH_CXXABI On)
else()
@ -169,19 +182,34 @@ endif()
# =============================================== Apply options to build ===============================================
function(check_backtrace_error)
if(NOT HAS_BACKTRACE)
if(NOT "${LIBCPP_BACKTRACE_PATH}" STREQUAL "")
message(WARNING "Cpptrace: LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE specified but libbacktrace doesn't appear installed or configured properly.")
else()
message(WARNING "Cpptrace: LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE specified but libbacktrace doesn't appear installed or configured properly. You may need to specify LIBCPP_BACKTRACE_PATH.")
endif()
endif()
endfunction()
# Full
if(LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE)
check_backtrace_error()
target_compile_definitions(cpptrace PUBLIC LIBCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE)
target_link_libraries(cpptrace PRIVATE backtrace)
endif()
# Symbols
if(LIBCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE)
check_backtrace_error()
target_compile_definitions(cpptrace PUBLIC LIBCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE)
endif()
# Unwinding
if(LIBCPPTRACE_UNWIND_WITH_EXECINFO)
if(NOT HAS_EXECINFO)
message(WARNING "Cpptrace: LIBCPPTRACE_UNWIND_WITH_EXECINFO specified but execinfo.h doesn't seem to be available.")
endif()
target_compile_definitions(cpptrace PUBLIC LIBCPPTRACE_UNWIND_WITH_EXECINFO)
endif()
@ -191,6 +219,9 @@ endif()
# Demangling
if(LIBCPPTRACE_DEMANGLE_WITH_CXXABI)
if(NOT HAS_CXXABI)
message(WARNING "Cpptrace: LIBCPPTRACE_DEMANGLE_WITH_CXXABI specified but cxxabi.h doesn't seem to be available.")
endif()
target_compile_definitions(cpptrace PUBLIC LIBCPPTRACE_DEMANGLE_WITH_CXXABI)
endif()
@ -198,6 +229,12 @@ if(LIBCPPTRACE_DEMANGLE_WITH_NOTHING)
target_compile_definitions(cpptrace PUBLIC LIBCPPTRACE_DEMANGLE_WITH_NOTHING)
endif()
if(NOT "${LIBCPP_BACKTRACE_PATH}" STREQUAL "")
target_compile_definitions(cpptrace PUBLIC LIBCPP_BACKTRACE_PATH=${LIBCPP_BACKTRACE_PATH})
endif()
# ======================================================================================================================
target_link_libraries(
cpptrace
PRIVATE

View File

@ -1,4 +1,6 @@
# libcpptrace
# Cpptrace
[![build](https://github.com/jeremy-rifkin/cpptrace/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/jeremy-rifkin/cpptrace/actions/workflows/build.yml)
Libcpptrace is a lightweight C++ stacktrace library supporting C++11 and greater on Linux, Unix, MacOS, and Windows
(including cygwin / mingw environments). The goal: Make traces simple for once.

View File

@ -1,4 +1,8 @@
#ifdef LIBCPP_BACKTRACE_PATH
#include LIBCPP_BACKTRACE_PATH
#else
#include <backtrace.h>
#endif
int main() {
backtrace_state* state = backtrace_create_state(nullptr, true, nullptr, nullptr);

View File

@ -1,6 +1,6 @@
#include <execinfo.h>
#include <cxxabi.h>
int main() {
void* frames[10];
int size = backtrace(frames, 10);
int status;
abi::__cxa_demangle("_Z3foov", nullptr, nullptr, &status);
}

View File

@ -1,5 +1,6 @@
#include <backtrace.h>
#include <execinfo.h>
int main() {
backtrace_state* state = backtrace_create_state(nullptr, true, nullptr, nullptr);
void* frames[10];
backtrace(frames, 10);
}

View File

@ -3,8 +3,6 @@
#include <cpptrace/cpptrace.hpp>
#include "libcpp_demangle.hpp"
#include <cxxabi.h>
#include <cstdlib>
#include <string>

View File

@ -6,7 +6,11 @@
#include <vector>
#ifdef LIBCPP_BACKTRACE_PATH
#include LIBCPP_BACKTRACE_PATH
#else
#include <backtrace.h>
#endif
namespace cpptrace {
namespace detail {

View File

@ -1,5 +1,5 @@
#ifndef LIBCPP_SYMBOLIZE_HPP
#define LIBCPP_SYMBOLIZE_HPP
#ifndef LIBCPP_SYMBOLS_HPP
#define LIBCPP_SYMBOLS_HPP
#include <cpptrace/cpptrace.hpp>
@ -10,7 +10,7 @@ namespace cpptrace {
namespace detail {
class symbolizer {
struct impl;
std::unique_ptr<impl> impl;
std::unique_ptr<impl> pimpl;
public:
symbolizer();
~symbolizer();

View File

@ -1,16 +1,33 @@
#ifdef LIBCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE
#include <cpptrace/cpptrace.hpp>
#include "libcpp_symbolize.hpp"
#include "libcpp_symbols.hpp"
#include "../platform/libcpp_program_name.hpp"
#include <memory>
#include <vector>
#ifdef LIBCPP_BACKTRACE_PATH
#include LIBCPP_BACKTRACE_PATH
#else
#include <backtrace.h>
#endif
namespace cpptrace {
namespace detail {
int full_callback(void* data, uintptr_t address, const char* file, int line, const char* symbol) {
stacktrace_frame& frame = *static_cast<stacktrace_frame*>(data);
frame.address = address;
frame.line = line;
frame.filename = file ? file : "";
frame.symbol = symbol ? symbol : "";
return 0;
}
void error_callback(void*, const char*, int) {
// nothing at the moment
}
backtrace_state* get_backtrace_state() {
// backtrace_create_state must be called only one time per program
static backtrace_state* state = nullptr;
@ -22,26 +39,6 @@ namespace cpptrace {
return state;
}
int full_callback(void* data, uintptr_t address, const char* file, int line, const char* symbol) {
stacktrace_frame& frame = *static_cast<stacktrace_frame*>(data);
data.address = address;
data.line = line;
data.filename = file ? file : "";
data.symbol = symbol ? symbol : "";
return 0;
}
void error_callback(void*, const char*, int) {
// nothing at the moment
}
symbolizer::symbolizer() : impl(std::make_unique<impl>()) {}
symbolizer::~symbolizer() = default;
stacktrace_frame symbolizer::resolve_frame(void* addr) {
impl->resolve_frame(addr);
}
// TODO: Handle backtrace_pcinfo calling the callback multiple times on inlined functions
struct symbolizer::impl {
stacktrace_frame resolve_frame(void* addr) {
@ -57,6 +54,13 @@ namespace cpptrace {
return frame;
}
};
symbolizer::symbolizer() : pimpl{new impl} {}
symbolizer::~symbolizer() = default;
stacktrace_frame symbolizer::resolve_frame(void* addr) {
return pimpl->resolve_frame(addr);
}
}
}

View File

@ -1,7 +1,7 @@
#ifdef LIBCPPTRACE_GET_SYMBOLS_WITH_NOTHING
#include <cpptrace/cpptrace.hpp>
#include "libcpp_symbolize.hpp"
#include "libcpp_symbols.hpp"
#include "../platform/libcpp_program_name.hpp"
#include <vector>

View File

@ -11,7 +11,7 @@ namespace cpptrace {
namespace detail {
std::vector<void*> capture_frames() {
std::vector<void*> frames(hard_max_frames, nullptr);
int n_frames = backtrace(bt.data(), hard_max_frames);
int n_frames = backtrace(frames.data(), hard_max_frames);
frames.resize(n_frames);
frames.shrink_to_fit();
return frames;

View File

@ -11,11 +11,11 @@ namespace cpptrace {
namespace detail {
std::vector<void*> capture_frames() {
// TODO: When does this need to be called? Can it be moved to the symbolizer?
SymSetOptions(SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);
HANDLE proc = GetCurrentProcess();
if(!SymInitialize(proc, NULL, TRUE)) return {};
//SymSetOptions(SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);
//HANDLE proc = GetCurrentProcess();
//if(!SymInitialize(proc, NULL, TRUE)) return {};
std::vector<PVOID> addrs(hard_max_frames, nullptr);
int frames = CaptureStackBackTrace(n_skip, hard_max_frames, addrs.data(), NULL);
int frames = CaptureStackBackTrace(0, hard_max_frames, addrs.data(), NULL);
addrs.resize(frames);
addrs.shrink_to_fit();
return addrs;