Add unit tests to CI (#140)
This commit is contained in:
parent
ce075b056f
commit
7a9ed920d5
57
.github/workflows/test.yml
vendored
57
.github/workflows/test.yml
vendored
@ -136,3 +136,60 @@ jobs:
|
||||
- name: build and test
|
||||
run: |
|
||||
python3 ci/test-all-configs.py --${{matrix.compiler}}
|
||||
|
||||
|
||||
unittest-linux:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
compiler: [g++-10, clang++-14]
|
||||
shared: [OFF, ON]
|
||||
build_type: [Debug, RelWithDebInfo]
|
||||
has_dl_find_object: [OFF, ON]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: dependencies
|
||||
run: |
|
||||
sudo apt install gcc-10 g++-10 libgcc-10-dev ninja-build
|
||||
- name: build and test
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
|
||||
-DCMAKE_C_COMPILER=${{matrix.compiler == 'g++-10' && 'gcc-10' || 'clang-14'}} \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DBUILD_SHARED_LIBS=${{matrix.shared}} \
|
||||
-DHAS_DL_FIND_OBJECT=${{matrix.has_dl_find_object}} \
|
||||
-DCPPTRACE_WERROR_BUILD=On \
|
||||
-DCPPTRACE_BUILD_TESTING=On
|
||||
ninja
|
||||
./unittest
|
||||
bash -c "exec -a u ./unittest"
|
||||
unittest-windows:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
compiler: [cl, clang++]
|
||||
shared: [OFF] # TODO: Re-enable shared
|
||||
build_type: [Debug, RelWithDebInfo]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Enable Developer Command Prompt
|
||||
uses: ilammy/msvc-dev-cmd@v1.13.0
|
||||
- name: build and test
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. `
|
||||
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
|
||||
-DCMAKE_C_COMPILER=${{matrix.compiler == 'clang++' && 'clang' || matrix.compiler}} `
|
||||
-DBUILD_SHARED_LIBS=${{matrix.shared}} `
|
||||
-DCPPTRACE_WERROR_BUILD=On `
|
||||
-DCPPTRACE_BUILD_TESTING=On
|
||||
cmake --build . --config ${{matrix.build_type}}
|
||||
./${{matrix.build_type}}/unittest
|
||||
# TODO: Macos, mingw
|
||||
|
||||
@ -10,7 +10,9 @@ cd build
|
||||
cmake .. -DZSTD_BUILD_SHARED=On -DZSTD_BUILD_SHARED=Off -DZSTD_LEGACY_SUPPORT=Off -DZSTD_BUILD_PROGRAMS=Off -DZSTD_BUILD_CONTRIB=Off -DZSTD_BUILD_TESTS=Off -G"Unix Makefiles"
|
||||
make -j
|
||||
make install
|
||||
|
||||
cd ../../../..
|
||||
|
||||
mkdir libdwarf
|
||||
cd libdwarf
|
||||
git init
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#!/bin/bash
|
||||
sudo apt install libgtest-dev
|
||||
|
||||
mkdir zstd
|
||||
cd zstd
|
||||
git init
|
||||
@ -7,7 +9,9 @@ git fetch --depth 1 origin 63779c798237346c2b245c546c40b72a5a5913fe # 1.5.5
|
||||
git checkout FETCH_HEAD
|
||||
make -j
|
||||
sudo make install
|
||||
|
||||
cd ..
|
||||
|
||||
mkdir libdwarf
|
||||
cd libdwarf
|
||||
git init
|
||||
|
||||
@ -177,7 +177,7 @@ def build(matrix):
|
||||
f"-D{matrix['demangle']}=On",
|
||||
"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
|
||||
"-DCPPTRACE_BUILD_TESTING=On",
|
||||
"-DCPPTRACE_IS_GH_ACTIONS=On",
|
||||
"-DCPPTRACE_SKIP_UNIT=On",
|
||||
f"-DBUILD_SHARED_LIBS={matrix['shared']}"
|
||||
]
|
||||
if matrix['symbols'] == "CPPTRACE_GET_SYMBOLS_WITH_LIBDL":
|
||||
@ -200,7 +200,7 @@ def build(matrix):
|
||||
f"-D{matrix['symbols']}=On",
|
||||
f"-D{matrix['demangle']}=On",
|
||||
"-DCPPTRACE_BUILD_TESTING=On",
|
||||
"-DCPPTRACE_IS_GH_ACTIONS=On",
|
||||
"-DCPPTRACE_SKIP_UNIT=On",
|
||||
f"-DBUILD_SHARED_LIBS={matrix['shared']}"
|
||||
]
|
||||
if matrix["compiler"] == "g++":
|
||||
@ -227,7 +227,7 @@ def build_full_or_auto(matrix):
|
||||
f"-DCPPTRACE_WERROR_BUILD=On",
|
||||
f"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
|
||||
"-DCPPTRACE_BUILD_TESTING=On",
|
||||
"-DCPPTRACE_IS_GH_ACTIONS=On",
|
||||
"-DCPPTRACE_SKIP_UNIT=On",
|
||||
f"-DBUILD_SHARED_LIBS={matrix['shared']}"
|
||||
]
|
||||
if matrix["config"] != "":
|
||||
@ -247,7 +247,7 @@ def build_full_or_auto(matrix):
|
||||
f"-DCPPTRACE_USE_EXTERNAL_ZSTD=On",
|
||||
f"-DCPPTRACE_WERROR_BUILD=On",
|
||||
"-DCPPTRACE_BUILD_TESTING=On",
|
||||
"-DCPPTRACE_IS_GH_ACTIONS=On",
|
||||
"-DCPPTRACE_SKIP_UNIT=On",
|
||||
f"-DBUILD_SHARED_LIBS={matrix['shared']}"
|
||||
]
|
||||
if matrix["config"] != "":
|
||||
|
||||
@ -166,7 +166,7 @@ option(CPPTRACE_VCPKG "" OFF)
|
||||
option(CPPTRACE_SANITIZER_BUILD "" OFF)
|
||||
option(CPPTRACE_WERROR_BUILD "" OFF)
|
||||
option(CPPTRACE_POSITION_INDEPENDENT_CODE "" ON)
|
||||
option(CPPTRACE_IS_GH_ACTIONS "" OFF)
|
||||
option(CPPTRACE_SKIP_UNIT "" OFF)
|
||||
option(CPPTRACE_USE_EXTERNAL_GTEST "" OFF)
|
||||
|
||||
mark_as_advanced(
|
||||
@ -177,6 +177,6 @@ mark_as_advanced(
|
||||
CPPTRACE_WERROR_BUILD
|
||||
CPPTRACE_CONAN
|
||||
CPPTRACE_VCPKG
|
||||
CPPTRACE_IS_GH_ACTIONS
|
||||
CPPTRACE_SKIP_UNIT
|
||||
CPPTRACE_USE_EXTERNAL_GTEST
|
||||
)
|
||||
|
||||
@ -37,7 +37,7 @@ if(UNIX)
|
||||
endif()
|
||||
|
||||
# primarily a workaround for github actions issue https://github.com/actions/runner-images/issues/8659
|
||||
if(NOT CPPTRACE_IS_GH_ACTIONS)
|
||||
if(NOT CPPTRACE_SKIP_UNIT)
|
||||
if(CPPTRACE_USE_EXTERNAL_GTEST)
|
||||
find_package(GTest)
|
||||
else()
|
||||
@ -60,6 +60,6 @@ if(NOT CPPTRACE_IS_GH_ACTIONS)
|
||||
)
|
||||
target_compile_features(unittest PRIVATE cxx_std_20)
|
||||
target_link_libraries(unittest PRIVATE ${target_name} GTest::gtest_main GTest::gmock_main)
|
||||
target_compile_options(unittest PRIVATE ${warning_options} -Wno-pedantic)
|
||||
target_compile_options(unittest PRIVATE ${warning_options} $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-pedantic -Wno-attributes>)
|
||||
add_test(NAME unittest COMMAND unittest)
|
||||
endif()
|
||||
|
||||
@ -49,16 +49,25 @@ TEST(ObjectTrace, BasicResolution) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void object_resolve_3(std::vector<int>& line_numbers) {
|
||||
// TODO: dbghelp uses raw address, not object
|
||||
#ifndef _MSC_VER
|
||||
CPPTRACE_FORCE_NO_INLINE int object_resolve_3(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
auto dummy = cpptrace::generate_trace();
|
||||
auto dummy_otrace = cpptrace::generate_object_trace();
|
||||
cpptrace::object_trace otrace;
|
||||
otrace.frames.push_back(cpptrace::object_frame{0, dummy.frames[0].object_address, dummy_otrace.frames[0].object_path});
|
||||
otrace.frames.push_back(cpptrace::object_frame{0, dummy.frames[1].object_address, dummy_otrace.frames[1].object_path});
|
||||
otrace.frames.push_back(cpptrace::object_frame{0, dummy.frames[2].object_address, dummy_otrace.frames[2].object_path});
|
||||
otrace.frames.push_back(cpptrace::object_frame{0, dummy.frames[3].object_address, dummy_otrace.frames[3].object_path});
|
||||
otrace.frames.push_back(
|
||||
cpptrace::object_frame{0, dummy.frames[0].object_address, dummy_otrace.frames[0].object_path}
|
||||
);
|
||||
otrace.frames.push_back(
|
||||
cpptrace::object_frame{0, dummy.frames[1].object_address, dummy_otrace.frames[1].object_path}
|
||||
);
|
||||
otrace.frames.push_back(
|
||||
cpptrace::object_frame{0, dummy.frames[2].object_address, dummy_otrace.frames[2].object_path}
|
||||
);
|
||||
otrace.frames.push_back(
|
||||
cpptrace::object_frame{0, dummy.frames[3].object_address, dummy_otrace.frames[3].object_path}
|
||||
);
|
||||
auto trace = otrace.resolve();
|
||||
int i = 0;
|
||||
EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("object_trace.cpp"));
|
||||
@ -76,16 +85,17 @@ CPPTRACE_FORCE_NO_INLINE void object_resolve_3(std::vector<int>& line_numbers) {
|
||||
EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("object_trace.cpp"));
|
||||
EXPECT_EQ(trace.frames[i].line.value(), line_numbers[i]);
|
||||
EXPECT_THAT(trace.frames[i].symbol, testing::HasSubstr("ObjectTrace_Resolution_Test::TestBody"));
|
||||
return 2;
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void object_resolve_2(std::vector<int>& line_numbers) {
|
||||
CPPTRACE_FORCE_NO_INLINE int object_resolve_2(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
object_resolve_3(line_numbers);
|
||||
return object_resolve_3(line_numbers) * 2;
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void object_resolve_1(std::vector<int>& line_numbers) {
|
||||
CPPTRACE_FORCE_NO_INLINE int object_resolve_1(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
object_resolve_2(line_numbers);
|
||||
return object_resolve_2(line_numbers) * 2;
|
||||
}
|
||||
|
||||
TEST(ObjectTrace, Resolution) {
|
||||
@ -93,3 +103,4 @@ TEST(ObjectTrace, Resolution) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
object_resolve_1(line_numbers);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -16,7 +16,8 @@ using namespace std::literals;
|
||||
|
||||
// This is fickle, however, it's the only way to do it really. It's reasonably reliable test in practice.
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_basic() {
|
||||
// NOTE: MSVC likes creating trampoline-like entries for non-static functions
|
||||
CPPTRACE_FORCE_NO_INLINE static void raw_trace_basic() {
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
// look for within 90 bytes of the start of the function
|
||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_basic));
|
||||
@ -28,7 +29,14 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_basic_precise() {
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
b:
|
||||
// look for within 30 bytes of the start of the function
|
||||
// This is stupid, but without it gcc was optimizing both &&a and &&b to point to the start of the function's body
|
||||
volatile auto x = 0;
|
||||
if(x) {
|
||||
goto* &&a;
|
||||
}
|
||||
if(x) {
|
||||
goto* &&b;
|
||||
}
|
||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&a));
|
||||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&b));
|
||||
}
|
||||
@ -39,11 +47,12 @@ TEST(RawTrace, Basic) {
|
||||
#ifndef _MSC_VER
|
||||
raw_trace_basic_precise();
|
||||
#endif
|
||||
[[maybe_unused]] volatile int x = 0; // prevent raw_trace_basic_precise() above being a jmp
|
||||
}
|
||||
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_2(
|
||||
CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_2(
|
||||
cpptrace::frame_ptr parent_low_bound,
|
||||
cpptrace::frame_ptr parent_high_bound
|
||||
) {
|
||||
@ -54,7 +63,7 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_2(
|
||||
EXPECT_LE(raw_trace.frames[1], parent_high_bound);
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_1() {
|
||||
CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_1() {
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
raw_trace_multi_2(reinterpret_cast<uintptr_t>(raw_trace_multi_1), reinterpret_cast<uintptr_t>(raw_trace_multi_1) + 300);
|
||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_1));
|
||||
@ -63,8 +72,8 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_1() {
|
||||
|
||||
std::vector<std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr>> parents;
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void record_parent(cpptrace::frame_ptr low_bound, cpptrace::frame_ptr high_bound) {
|
||||
parents.insert(parents.begin(), {reinterpret_cast<uintptr_t>(low_bound), reinterpret_cast<uintptr_t>(high_bound)});
|
||||
CPPTRACE_FORCE_NO_INLINE void record_parent(uintptr_t low_bound, uintptr_t high_bound) {
|
||||
parents.insert(parents.begin(), {low_bound, high_bound});
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@ -72,6 +81,13 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_3() {
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
b:
|
||||
volatile auto x = 0;
|
||||
if(x) {
|
||||
goto* &&a;
|
||||
}
|
||||
if(x) {
|
||||
goto* &&b;
|
||||
}
|
||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&a)); // this frame
|
||||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&b));
|
||||
for(size_t i = 0; i < parents.size(); i++) { // parent frames
|
||||
@ -84,6 +100,13 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_2() {
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
b:
|
||||
volatile auto x = 0;
|
||||
if(x) {
|
||||
goto* &&a;
|
||||
}
|
||||
if(x) {
|
||||
goto* &&b;
|
||||
}
|
||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&a)); // this frame
|
||||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&b));
|
||||
for(size_t i = 0; i < parents.size(); i++) { // parent frames
|
||||
@ -93,19 +116,38 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_2() {
|
||||
record_parent(reinterpret_cast<uintptr_t>(&&c), reinterpret_cast<uintptr_t>(&&d));
|
||||
c:
|
||||
raw_trace_multi_precise_3();
|
||||
d:;
|
||||
d:
|
||||
if(x) {
|
||||
goto* &&c;
|
||||
}
|
||||
if(x) {
|
||||
goto* &&d;
|
||||
}
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_1() {
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
b:
|
||||
volatile auto x = 0;
|
||||
if(x) {
|
||||
goto* &&a;
|
||||
}
|
||||
if(x) {
|
||||
goto* &&b;
|
||||
}
|
||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&a));
|
||||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&b));
|
||||
record_parent(reinterpret_cast<uintptr_t>(&&c), reinterpret_cast<uintptr_t>(&&d));
|
||||
c:
|
||||
raw_trace_multi_precise_2();
|
||||
d:;
|
||||
d:
|
||||
if(x) {
|
||||
goto* &&c;
|
||||
}
|
||||
if(x) {
|
||||
goto* &&d;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -42,7 +42,9 @@ TEST(Stacktrace, Basic) {
|
||||
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_multi_3(std::vector<int>& line_numbers) {
|
||||
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * 2; later helps prevent the call from
|
||||
// being optimized to a jmp
|
||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_3(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
auto trace = cpptrace::generate_trace();
|
||||
int i = 0;
|
||||
@ -61,16 +63,17 @@ CPPTRACE_FORCE_NO_INLINE void stacktrace_multi_3(std::vector<int>& line_numbers)
|
||||
EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("stacktrace.cpp"));
|
||||
EXPECT_EQ(trace.frames[i].line.value(), line_numbers[i]);
|
||||
EXPECT_THAT(trace.frames[i].symbol, testing::HasSubstr("Stacktrace_MultipleFrames_Test::TestBody"));
|
||||
return 2;
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_multi_2(std::vector<int>& line_numbers) {
|
||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_2(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
stacktrace_multi_3(line_numbers);
|
||||
return stacktrace_multi_3(line_numbers) * 2;
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_multi_1(std::vector<int>& line_numbers) {
|
||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_1(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
stacktrace_multi_2(line_numbers);
|
||||
return stacktrace_multi_2(line_numbers) * 2;
|
||||
}
|
||||
|
||||
TEST(Stacktrace, MultipleFrames) {
|
||||
@ -121,7 +124,8 @@ TEST(Stacktrace, RawTraceResolution) {
|
||||
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_inline_resolution_3(std::vector<int>& line_numbers) {
|
||||
#ifndef _MSC_VER
|
||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_3(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
auto trace = cpptrace::generate_trace();
|
||||
int i = 0;
|
||||
@ -152,16 +156,17 @@ CPPTRACE_FORCE_NO_INLINE void stacktrace_inline_resolution_3(std::vector<int>& l
|
||||
EXPECT_FALSE(trace.frames[i].is_inline);
|
||||
EXPECT_NE(trace.frames[i].raw_address, 0);
|
||||
EXPECT_NE(trace.frames[i].object_address, 0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_INLINE void stacktrace_inline_resolution_2(std::vector<int>& line_numbers) {
|
||||
CPPTRACE_FORCE_INLINE int stacktrace_inline_resolution_2(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
stacktrace_inline_resolution_3(line_numbers);
|
||||
return stacktrace_inline_resolution_3(line_numbers) * 2;
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_inline_resolution_1(std::vector<int>& line_numbers) {
|
||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_1(std::vector<int>& line_numbers) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
stacktrace_inline_resolution_2(line_numbers);
|
||||
return stacktrace_inline_resolution_2(line_numbers) * 2;
|
||||
}
|
||||
|
||||
TEST(Stacktrace, InlineResolution) {
|
||||
@ -169,3 +174,4 @@ TEST(Stacktrace, InlineResolution) {
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
stacktrace_inline_resolution_1(line_numbers);
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user