Try to add basic performance testing (#8)

This commit is contained in:
Jeremy Rifkin 2023-07-13 21:54:17 -04:00 committed by GitHub
parent 6b55222a4b
commit d955c61cd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 230 additions and 43 deletions

76
.github/workflows/performance-tests.yml vendored Normal file
View File

@ -0,0 +1,76 @@
name: performance-test
on:
push:
pull_request:
jobs:
test-linux:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-11, clang++-14]
target: [Debug]
std: [11, 20]
config: [
"-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On",
"-DCPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE=On -DCPPTRACE_BUILD_SPEEDTEST_DWARF4=On",
"-DCPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE=On -DCPPTRACE_BUILD_SPEEDTEST_DWARF5=On"
]
exclude:
- config: -DCPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE=On -DCPPTRACE_BUILD_SPEEDTEST_DWARF5=On
compiler: g++-11
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-11 g++-11 libgcc-11-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}} \
${{matrix.config}} \
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/11/include/backtrace.h \
-DCPPTRACE_BUILD_SPEEDTEST=On \
-DBUILD_SHARED_LIBS=On
make
- name: test
working-directory: build
run: |
./speedtest | python3 ../test/speedtest.py ${{matrix.config}}
# TODO: For some reason this is slow on github's runner
#test-windows:
# runs-on: windows-2019
# strategy:
# fail-fast: false
# matrix:
# compiler: [cl, clang++]
# target: [Debug]
# std: [11, 20]
# config: [
# "-DCPPTRACE_GET_SYMBOLS_WITH_DBGHELP=On"
# ]
# 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}} `
# -DCPPTRACE_BUILD_SPEEDTEST=On `
# -DBUILD_SHARED_LIBS=On
# msbuild .\cpptrace.sln
# - name: test
# working-directory: build
# run: |
# .\${{matrix.target}}\speedtest.exe | python3 ../test/speedtest.py ${{matrix.config}}

View File

@ -67,6 +67,10 @@ option(CPPTRACE_DEMANGLE_WITH_NOTHING "" OFF)
option(CPPTRACE_BUILD_TEST "" OFF)
option(CPPTRACE_BUILD_TEST_RDYNAMIC "" OFF)
option(CPPTRACE_BUILD_SPEEDTEST "" OFF)
option(CPPTRACE_BUILD_SPEEDTEST_DWARF4 "" OFF)
option(CPPTRACE_BUILD_SPEEDTEST_DWARF5 "" OFF)
set(CPPTRACE_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.")
set(CPPTRACE_HARD_MAX_FRAMES "" CACHE STRING "Hard limit on unwinding depth. Default is 100.")
@ -371,3 +375,47 @@ if(CPPTRACE_BUILD_TEST)
set_property(TARGET test PROPERTY ENABLE_EXPORTS ON)
endif()
endif()
if(CPPTRACE_BUILD_SPEEDTEST)
if(CPPTRACE_BUILD_SPEEDTEST_DWARF4)
check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4)
if(HAS_DWARF4)
add_compile_options("$<$<CONFIG:Debug>:-gdwarf-4>")
#target_compile_options(speedtest PRIVATE "$<$<CONFIG:Debug>:-gdwarf-4>")
#target_compile_options(googletest INTERFACE "$<$<CONFIG:Debug>:-gdwarf-4>")
endif()
endif()
if(CPPTRACE_BUILD_SPEEDTEST_DWARF5)
check_cxx_compiler_flag("-gdwarf-5" HAS_DWARF5)
if(HAS_DWARF5)
add_compile_options("$<$<CONFIG:Debug>:-gdwarf-5>")
#target_compile_options(speedtest PRIVATE "$<$<CONFIG:Debug>:-gdwarf-4>")
#target_compile_options(googletest INTERFACE "$<$<CONFIG:Debug>:-gdwarf-4>")
endif()
endif()
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_executable(speedtest test/speedtest.cpp)
target_link_libraries(
speedtest
PRIVATE
GTest::gtest_main
cpptrace
)
if(WIN32)
add_custom_command(
TARGET speedtest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:speedtest> $<TARGET_FILE_DIR:speedtest>
COMMAND_EXPAND_LISTS
)
endif()
endif()

View File

@ -2,6 +2,7 @@
[![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)
[![test](https://github.com/jeremy-rifkin/cpptrace/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/jeremy-rifkin/cpptrace/actions/workflows/test.yml)
[![performance-test](https://github.com/jeremy-rifkin/cpptrace/actions/workflows/performance-tests.yml/badge.svg)](https://github.com/jeremy-rifkin/cpptrace/actions/workflows/performance-tests.yml)
🚧 WIP 🏗️

View File

@ -44,6 +44,22 @@ namespace cpptrace {
return frames;
}
bool has_addr2line() {
// Detects if addr2line exists by trying to invoke addr2line --help
constexpr int magic = 42;
pid_t pid = fork();
if(pid == -1) { return false; }
if(pid == 0) { // child
close(STDOUT_FILENO);
// TODO: path
execlp("addr2line", "addr2line", "--help", nullptr);
exit(magic);
}
int status;
waitpid(pid, &status, 0);
return WEXITSTATUS(status) == 0;
}
struct pipe_t {
union {
struct {
@ -93,6 +109,7 @@ namespace cpptrace {
struct symbolizer::impl {
std::vector<stacktrace_frame> resolve_frames(const std::vector<void*>& frames) {
std::vector<stacktrace_frame> trace(frames.size(), stacktrace_frame { 0, 0, 0, "", "" });
if(has_addr2line()) {
std::vector<dlframe> dlframes = backtrace_frames(frames);
std::unordered_map<
std::string,
@ -141,6 +158,7 @@ namespace cpptrace {
}
}
}
}
return trace;
}
};

11
test/speedtest.cpp Normal file
View File

@ -0,0 +1,11 @@
// https://github.com/jeremy-rifkin/libassert/issues/43
#include <cpptrace/cpptrace.hpp>
#include <gtest/gtest.h>
#include <exception>
TEST(TraceTest, trace_test) {
ASSERT_THROW((cpptrace::print_trace(), false), std::logic_error);
}

33
test/speedtest.py Normal file
View File

@ -0,0 +1,33 @@
import sys
import re
def main():
output = sys.stdin.read()
print(output)
print("-" * 50)
time = int(re.search(r"\d+ tests? from \d+ test suites? ran. \((\d+) ms total\)", output).group(1))
dwarf4 = any(["DWARF4" in arg for arg in sys.argv[1:]])
dwarf5 = any(["DWARF5" in arg for arg in sys.argv[1:]])
expect_slow = dwarf4
threshold = 100 # ms
if expect_slow:
if time > 100:
print(f"Success (expecting slow): Test program took {time} ms")
else:
print(f"Error (expecting slow): Test program took {time} ms")
sys.exit(1)
else:
if time > 100:
print(f"Error: Test program took {time} ms")
sys.exit(1)
else:
print(f"Success: Test program took {time} ms")
main()