Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fac4d08fd0 | ||
|
|
c0354799c7 |
46
.github/workflows/ci.yml
vendored
46
.github/workflows/ci.yml
vendored
@ -25,6 +25,26 @@ jobs:
|
|||||||
- name: build and test
|
- name: build and test
|
||||||
run: |
|
run: |
|
||||||
python3 ci/test-all-configs.py --${{matrix.compiler}} --default-config
|
python3 ci/test-all-configs.py --${{matrix.compiler}} --default-config
|
||||||
|
test-linux-arm:
|
||||||
|
runs-on: ubuntu-22.04-arm
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
compiler: [gcc, clang]
|
||||||
|
shared: [--shared, ""]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt install gcc-10 g++-10 libgcc-10-dev libunwind8-dev
|
||||||
|
pip3 install colorama
|
||||||
|
- name: libdwarf
|
||||||
|
run: |
|
||||||
|
cd ..
|
||||||
|
cpptrace/ci/setup-prerequisites.sh
|
||||||
|
- name: build and test
|
||||||
|
run: |
|
||||||
|
python3 ci/test-all-configs.py --${{matrix.compiler}} --default-config
|
||||||
test-macos:
|
test-macos:
|
||||||
runs-on: macos-14
|
runs-on: macos-14
|
||||||
strategy:
|
strategy:
|
||||||
@ -562,6 +582,32 @@ jobs:
|
|||||||
- name: test opt
|
- name: test opt
|
||||||
run: |
|
run: |
|
||||||
bazel test //... -c opt
|
bazel test //... -c opt
|
||||||
|
unittest-linux-arm:
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
compiler: [g++-10, clang++-18]
|
||||||
|
stdlib: [libstdc++, libc++]
|
||||||
|
dwarf_version: [4, 5]
|
||||||
|
split_dwarf: [OFF, ON]
|
||||||
|
exclude:
|
||||||
|
- compiler: g++-10
|
||||||
|
stdlib: libc++
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt install gcc-10 g++-10 libgcc-10-dev ninja-build libc++-dev
|
||||||
|
cd ..
|
||||||
|
cpptrace/ci/setup-prerequisites-unittest.sh
|
||||||
|
- name: build and test
|
||||||
|
run: |
|
||||||
|
python3 ci/unittest.py \
|
||||||
|
--slice=compiler:${{matrix.compiler}} \
|
||||||
|
--slice=stdlib:${{matrix.stdlib}} \
|
||||||
|
--slice=dwarf_version:${{matrix.dwarf_version}} \
|
||||||
|
--slice=split_dwarf:${{matrix.split_dwarf}}
|
||||||
unittest-macos:
|
unittest-macos:
|
||||||
runs-on: macos-14
|
runs-on: macos-14
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@ -34,20 +34,12 @@ endif()
|
|||||||
if(PROJECT_IS_TOP_LEVEL)
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
if(CMAKE_GENERATOR STREQUAL "Ninja")
|
if(CMAKE_GENERATOR STREQUAL "Ninja")
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
include(CheckCXXCompilerFlag)
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
|
||||||
check_cxx_compiler_flag(-fdiagnostics-color=always HAS_CXX_FDIAGNOSTICS_COLOR)
|
|
||||||
if(HAS_CXX_FDIAGNOSTICS_COLOR)
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
|
|
||||||
endif()
|
|
||||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||||
endif()
|
endif()
|
||||||
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||||
include(CheckCCompilerFlag)
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
|
||||||
check_c_compiler_flag(-fdiagnostics-color=always HAS_C_FDIAGNOSTICS_COLOR)
|
|
||||||
if(HAS_C_FDIAGNOSTICS_COLOR)
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
|
|
||||||
endif()
|
|
||||||
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
|
||||||
endif()
|
endif()
|
||||||
@ -184,11 +176,6 @@ target_compile_options(
|
|||||||
${warning_options}
|
${warning_options}
|
||||||
)
|
)
|
||||||
|
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
|
|
||||||
# https://godbolt.org/z/qYh89E6rq
|
|
||||||
target_compile_options(${target_name} PRIVATE -Wno-missing-field-initializers)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CPPTRACE_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR})
|
set(CPPTRACE_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR})
|
||||||
set(CPPTRACE_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR})
|
set(CPPTRACE_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR})
|
||||||
set(CPPTRACE_VERSION_PATCH ${CMAKE_PROJECT_VERSION_PATCH})
|
set(CPPTRACE_VERSION_PATCH ${CMAKE_PROJECT_VERSION_PATCH})
|
||||||
|
|||||||
@ -424,7 +424,7 @@ namespace detail {
|
|||||||
static std::unordered_map<std::string, Result<elf, internal_error>> cache;
|
static std::unordered_map<std::string, Result<elf, internal_error>> cache;
|
||||||
auto it = cache.find(object_path);
|
auto it = cache.find(object_path);
|
||||||
if(it == cache.end()) {
|
if(it == cache.end()) {
|
||||||
auto res = cache.emplace(object_path, elf::open_elf(object_path));
|
auto res = cache.insert({ object_path, elf::open_elf(object_path) });
|
||||||
VERIFY(res.second);
|
VERIFY(res.second);
|
||||||
it = res.first;
|
it = res.first;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -208,18 +208,19 @@ namespace cpptrace {
|
|||||||
const auto yellow = color ? YELLOW : "";
|
const auto yellow = color ? YELLOW : "";
|
||||||
const auto blue = color ? BLUE : "";
|
const auto blue = color ? BLUE : "";
|
||||||
if(frame.is_inline) {
|
if(frame.is_inline) {
|
||||||
microfmt::print(stream, "{<{}}", 2 * sizeof(frame_ptr) + 2, "(inlined)");
|
microfmt::print(stream, "{<{}} ", 2 * sizeof(frame_ptr) + 2, "(inlined)");
|
||||||
} else {
|
} else if(options.addresses != address_mode::none) {
|
||||||
auto address = options.addresses == address_mode::raw ? frame.raw_address : frame.object_address;
|
auto address = options.addresses == address_mode::raw ? frame.raw_address : frame.object_address;
|
||||||
microfmt::print(stream, "{}0x{>{}:0h}{}", blue, 2 * sizeof(frame_ptr), address, reset);
|
microfmt::print(stream, "{}0x{>{}:0h}{} ", blue, 2 * sizeof(frame_ptr), address, reset);
|
||||||
}
|
}
|
||||||
if(!frame.symbol.empty()) {
|
if(!frame.symbol.empty()) {
|
||||||
microfmt::print(stream, " in {}{}{}", yellow, frame.symbol, reset);
|
microfmt::print(stream, "in {}{}{}", yellow, frame.symbol, reset);
|
||||||
}
|
}
|
||||||
if(!frame.filename.empty()) {
|
if(!frame.filename.empty()) {
|
||||||
microfmt::print(
|
microfmt::print(
|
||||||
stream,
|
stream,
|
||||||
" at {}{}{}",
|
"{}at {}{}{}",
|
||||||
|
frame.symbol.empty() ? "" : " ",
|
||||||
green,
|
green,
|
||||||
options.paths == path_mode::full ? frame.filename : detail::basename(frame.filename, true),
|
options.paths == path_mode::full ? frame.filename : detail::basename(frame.filename, true),
|
||||||
reset
|
reset
|
||||||
|
|||||||
@ -272,8 +272,7 @@ namespace cpptrace {
|
|||||||
memcpy(new_vtable_page, type_info_vtable_pointer, vtable_size * sizeof(void*));
|
memcpy(new_vtable_page, type_info_vtable_pointer, vtable_size * sizeof(void*));
|
||||||
// ninja in the custom __do_catch interceptor
|
// ninja in the custom __do_catch interceptor
|
||||||
auto new_vtable = static_cast<void**>(new_vtable_page);
|
auto new_vtable = static_cast<void**>(new_vtable_page);
|
||||||
// double cast is done here because older (and some newer gcc versions) warned about it under -Wpedantic
|
new_vtable[6] = reinterpret_cast<void*>(do_catch_function);
|
||||||
new_vtable[6] = reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(do_catch_function));
|
|
||||||
// make the page read-only
|
// make the page read-only
|
||||||
mprotect_page(new_vtable_page, page_size, memory_readonly);
|
mprotect_page(new_vtable_page, page_size, memory_readonly);
|
||||||
|
|
||||||
|
|||||||
@ -324,7 +324,7 @@ namespace libdwarf {
|
|||||||
char** dw_srcfiles;
|
char** dw_srcfiles;
|
||||||
Dwarf_Signed dw_filecount;
|
Dwarf_Signed dw_filecount;
|
||||||
VERIFY(wrap(dwarf_srcfiles, cu_die.get(), &dw_srcfiles, &dw_filecount) == DW_DLV_OK);
|
VERIFY(wrap(dwarf_srcfiles, cu_die.get(), &dw_srcfiles, &dw_filecount) == DW_DLV_OK);
|
||||||
it = srcfiles_cache.emplace_hint(it, off, srcfiles{cu_die.dbg, dw_srcfiles, dw_filecount});
|
it = srcfiles_cache.insert(it, {off, srcfiles{cu_die.dbg, dw_srcfiles, dw_filecount}});
|
||||||
}
|
}
|
||||||
if(file_i < it->second.count()) {
|
if(file_i < it->second.count()) {
|
||||||
// dwarf is using 1-indexing
|
// dwarf is using 1-indexing
|
||||||
|
|||||||
@ -67,14 +67,7 @@ namespace libdwarf {
|
|||||||
// sorted range entries for dies
|
// sorted range entries for dies
|
||||||
template<
|
template<
|
||||||
typename T,
|
typename T,
|
||||||
typename std::enable_if<
|
typename std::enable_if<std::is_trivially_copyable<T>::value && sizeof(T) <= 16, int>::type = 0
|
||||||
// old gcc doesn't support this trait https://godbolt.org/z/fKWT9jTK7
|
|
||||||
#if !(defined(__GNUC__) && (__GNUC__ < 5))
|
|
||||||
std::is_trivially_copyable<T>::value &&
|
|
||||||
#endif
|
|
||||||
sizeof(T) <= 16,
|
|
||||||
int
|
|
||||||
>::type = 0
|
|
||||||
>
|
>
|
||||||
class die_cache {
|
class die_cache {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -24,13 +24,6 @@
|
|||||||
#define NODISCARD
|
#define NODISCARD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// workaround a bizarre gcc bug https://godbolt.org/z/s78vnf7jv
|
|
||||||
// https://github.com/jeremy-rifkin/cpptrace/issues/220
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 7)
|
|
||||||
#undef NODISCARD
|
|
||||||
#define NODISCARD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if IS_MSVC
|
#if IS_MSVC
|
||||||
#define MSVC_CDECL __cdecl
|
#define MSVC_CDECL __cdecl
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -96,6 +96,21 @@ TEST(FormatterTest, ObjectAddresses) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatterTest, NoAddresses) {
|
||||||
|
auto formatter = cpptrace::formatter{}
|
||||||
|
.addresses(cpptrace::formatter::address_mode::none);
|
||||||
|
auto res = split(formatter.format(make_test_stacktrace()), "\n");
|
||||||
|
EXPECT_THAT(
|
||||||
|
res,
|
||||||
|
ElementsAre(
|
||||||
|
"Stack trace (most recent call first):",
|
||||||
|
"#0 in foo() at foo.cpp:20:30",
|
||||||
|
"#1 in bar() at bar.cpp:30:40",
|
||||||
|
"#2 in main at foo.cpp:40:25"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, PathShortening) {
|
TEST(FormatterTest, PathShortening) {
|
||||||
cpptrace::stacktrace trace;
|
cpptrace::stacktrace trace;
|
||||||
trace.frames.push_back({0x1, 0x1001, {20}, {30}, "/home/foo/foo.cpp", "foo()", false});
|
trace.frames.push_back({0x1, 0x1001, {20}, {30}, "/home/foo/foo.cpp", "foo()", false});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user