LTO hackery, make unittests pass under LTO, closes #179
This commit is contained in:
parent
90da0563f9
commit
4cb425fb35
@ -13,21 +13,24 @@
|
|||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
|
||||||
// NOTE: returning something and then return stacktrace_from_current_3(line_numbers) * 2; later helps prevent the call from
|
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * rand(); is done to prevent TCO even
|
||||||
// being optimized to a jmp
|
// under LTO https://github.com/jeremy-rifkin/cpptrace/issues/179#issuecomment-2467302052
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_3(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
throw std::runtime_error("foobar");
|
throw std::runtime_error("foobar");
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_2(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_from_current_3(line_numbers) * 2;
|
return stacktrace_from_current_3(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_1(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_from_current_2(line_numbers) * 2;
|
return stacktrace_from_current_2(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FromCurrent, Basic) {
|
TEST(FromCurrent, Basic) {
|
||||||
|
|||||||
@ -13,27 +13,24 @@
|
|||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
|
||||||
// NOTE: returning something and then return stacktrace_from_current_3(line_numbers) * 2; later helps prevent the call from
|
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * rand(); is done to prevent TCO even
|
||||||
// being optimized to a jmp
|
// under LTO https://github.com/jeremy-rifkin/cpptrace/issues/179#issuecomment-2467302052
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_z_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_z_3(std::vector<int>& line_numbers) {
|
||||||
// just here to differentiate from the non-z version to prevent ICF if LTO is being used
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
[[maybe_unused]] volatile int x = 1;
|
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
throw std::runtime_error("foobar");
|
throw std::runtime_error("foobar");
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_z_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_z_2(std::vector<int>& line_numbers) {
|
||||||
// just here to differentiate from the non-z version to prevent ICF if LTO is being used
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
[[maybe_unused]] volatile int x = 1;
|
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_from_current_z_3(line_numbers) * 2;
|
return stacktrace_from_current_z_3(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_z_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_from_current_z_1(std::vector<int>& line_numbers) {
|
||||||
// just here to differentiate from the non-z version to prevent ICF if LTO is being used
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
[[maybe_unused]] volatile int x = 1;
|
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_from_current_z_2(line_numbers) * 2;
|
return stacktrace_from_current_z_2(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FromCurrentZ, Basic) {
|
TEST(FromCurrentZ, Basic) {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#include <random>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
@ -19,6 +20,7 @@ TEST(ObjectTrace, Empty) {
|
|||||||
|
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void object_basic() {
|
CPPTRACE_FORCE_NO_INLINE void object_basic() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
auto trace = cpptrace::generate_object_trace();
|
auto trace = cpptrace::generate_object_trace();
|
||||||
EXPECT_FALSE(trace.empty());
|
EXPECT_FALSE(trace.empty());
|
||||||
EXPECT_NE(trace.frames[0].raw_address, 0);
|
EXPECT_NE(trace.frames[0].raw_address, 0);
|
||||||
@ -33,6 +35,7 @@ TEST(ObjectTrace, Basic) {
|
|||||||
|
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void object_basic_resolution() {
|
CPPTRACE_FORCE_NO_INLINE void object_basic_resolution() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
auto line = __LINE__ + 1;
|
auto line = __LINE__ + 1;
|
||||||
auto trace = cpptrace::generate_object_trace().resolve();
|
auto trace = cpptrace::generate_object_trace().resolve();
|
||||||
ASSERT_GE(trace.frames.size(), 1);
|
ASSERT_GE(trace.frames.size(), 1);
|
||||||
@ -49,6 +52,7 @@ TEST(ObjectTrace, BasicResolution) {
|
|||||||
// TODO: dbghelp uses raw address, not object
|
// TODO: dbghelp uses raw address, not object
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
CPPTRACE_FORCE_NO_INLINE int object_resolve_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int object_resolve_3(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
auto dummy = cpptrace::generate_trace();
|
auto dummy = cpptrace::generate_trace();
|
||||||
auto dummy_otrace = cpptrace::generate_object_trace();
|
auto dummy_otrace = cpptrace::generate_object_trace();
|
||||||
@ -89,14 +93,18 @@ CPPTRACE_FORCE_NO_INLINE int object_resolve_3(std::vector<int>& line_numbers) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * rand(); is done to prevent TCO even
|
||||||
|
// under LTO https://github.com/jeremy-rifkin/cpptrace/issues/179#issuecomment-2467302052
|
||||||
CPPTRACE_FORCE_NO_INLINE int object_resolve_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int object_resolve_2(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return object_resolve_3(line_numbers) * 2;
|
return object_resolve_3(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int object_resolve_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int object_resolve_1(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return object_resolve_2(line_numbers) * 2;
|
return object_resolve_2(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ObjectTrace, Resolution) {
|
TEST(ObjectTrace, Resolution) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ using namespace std::literals;
|
|||||||
|
|
||||||
// NOTE: MSVC likes creating trampoline-like entries for non-static functions
|
// NOTE: MSVC likes creating trampoline-like entries for non-static functions
|
||||||
CPPTRACE_FORCE_NO_INLINE static void raw_trace_basic() {
|
CPPTRACE_FORCE_NO_INLINE static void raw_trace_basic() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
auto raw_trace = cpptrace::generate_raw_trace();
|
||||||
// look for within 90 bytes of the start of the function
|
// look for within 90 bytes of the start of the function
|
||||||
ASSERT_GE(raw_trace.frames.size(), 1);
|
ASSERT_GE(raw_trace.frames.size(), 1);
|
||||||
@ -27,6 +28,7 @@ CPPTRACE_FORCE_NO_INLINE static void raw_trace_basic() {
|
|||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_basic_precise() {
|
CPPTRACE_FORCE_NO_INLINE void raw_trace_basic_precise() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
a:
|
a:
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
auto raw_trace = cpptrace::generate_raw_trace();
|
||||||
b:
|
b:
|
||||||
@ -58,6 +60,7 @@ CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_2(
|
|||||||
cpptrace::frame_ptr parent_low_bound,
|
cpptrace::frame_ptr parent_low_bound,
|
||||||
cpptrace::frame_ptr parent_high_bound
|
cpptrace::frame_ptr parent_high_bound
|
||||||
) {
|
) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
auto raw_trace = cpptrace::generate_raw_trace();
|
||||||
ASSERT_GE(raw_trace.frames.size(), 2);
|
ASSERT_GE(raw_trace.frames.size(), 2);
|
||||||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_2));
|
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_2));
|
||||||
@ -67,6 +70,7 @@ CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_2(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_1() {
|
CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_1() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
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);
|
raw_trace_multi_2(reinterpret_cast<uintptr_t>(raw_trace_multi_1), reinterpret_cast<uintptr_t>(raw_trace_multi_1) + 300);
|
||||||
ASSERT_GE(raw_trace.frames.size(), 1);
|
ASSERT_GE(raw_trace.frames.size(), 1);
|
||||||
@ -77,11 +81,13 @@ CPPTRACE_FORCE_NO_INLINE static void raw_trace_multi_1() {
|
|||||||
std::vector<std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr>> parents;
|
std::vector<std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr>> parents;
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void record_parent(uintptr_t low_bound, uintptr_t high_bound) {
|
CPPTRACE_FORCE_NO_INLINE void record_parent(uintptr_t low_bound, uintptr_t high_bound) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
parents.insert(parents.begin(), {low_bound, high_bound});
|
parents.insert(parents.begin(), {low_bound, high_bound});
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_3() {
|
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_3() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
a:
|
a:
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
auto raw_trace = cpptrace::generate_raw_trace();
|
||||||
b:
|
b:
|
||||||
@ -102,6 +108,7 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_3() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_2() {
|
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_2() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
a:
|
a:
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
auto raw_trace = cpptrace::generate_raw_trace();
|
||||||
b:
|
b:
|
||||||
@ -132,6 +139,7 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_1() {
|
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_1() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
a:
|
a:
|
||||||
auto raw_trace = cpptrace::generate_raw_trace();
|
auto raw_trace = cpptrace::generate_raw_trace();
|
||||||
b:
|
b:
|
||||||
|
|||||||
@ -25,6 +25,7 @@ TEST(Stacktrace, Empty) {
|
|||||||
|
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_basic() {
|
CPPTRACE_FORCE_NO_INLINE void stacktrace_basic() {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
auto line = __LINE__ + 1;
|
auto line = __LINE__ + 1;
|
||||||
auto trace = cpptrace::generate_trace();
|
auto trace = cpptrace::generate_trace();
|
||||||
ASSERT_GE(trace.frames.size(), 1);
|
ASSERT_GE(trace.frames.size(), 1);
|
||||||
@ -39,9 +40,10 @@ TEST(Stacktrace, Basic) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * 2; later helps prevent the call from
|
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * rand(); is done to prevent TCO even
|
||||||
// being optimized to a jmp
|
// under LTO https://github.com/jeremy-rifkin/cpptrace/issues/179#issuecomment-2467302052
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_3(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
auto trace = cpptrace::generate_trace();
|
auto trace = cpptrace::generate_trace();
|
||||||
if(trace.frames.size() < 4) {
|
if(trace.frames.size() < 4) {
|
||||||
@ -68,13 +70,15 @@ CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_3(std::vector<int>& line_numbers)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_2(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_multi_3(line_numbers) * 2;
|
return stacktrace_multi_3(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_multi_1(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_multi_2(line_numbers) * 2;
|
return stacktrace_multi_2(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Stacktrace, MultipleFrames) {
|
TEST(Stacktrace, MultipleFrames) {
|
||||||
@ -86,16 +90,19 @@ TEST(Stacktrace, MultipleFrames) {
|
|||||||
|
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE cpptrace::raw_trace stacktrace_raw_resolve_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE cpptrace::raw_trace stacktrace_raw_resolve_3(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return cpptrace::generate_raw_trace();
|
return cpptrace::generate_raw_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE cpptrace::raw_trace stacktrace_raw_resolve_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE cpptrace::raw_trace stacktrace_raw_resolve_2(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_raw_resolve_3(line_numbers);
|
return stacktrace_raw_resolve_3(line_numbers);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE cpptrace::raw_trace stacktrace_raw_resolve_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE cpptrace::raw_trace stacktrace_raw_resolve_1(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_raw_resolve_2(line_numbers);
|
return stacktrace_raw_resolve_2(line_numbers);
|
||||||
}
|
}
|
||||||
@ -127,6 +134,7 @@ TEST(Stacktrace, RawTraceResolution) {
|
|||||||
|
|
||||||
#ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF
|
#ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_3(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
auto trace = cpptrace::generate_trace();
|
auto trace = cpptrace::generate_trace();
|
||||||
if(trace.frames.size() < 4) {
|
if(trace.frames.size() < 4) {
|
||||||
@ -165,13 +173,15 @@ CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_3(std::vector<int>& li
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_INLINE int stacktrace_inline_resolution_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_INLINE int stacktrace_inline_resolution_2(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_inline_resolution_3(line_numbers) * 2;
|
return stacktrace_inline_resolution_3(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_inline_resolution_1(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_inline_resolution_2(line_numbers) * 2;
|
return stacktrace_inline_resolution_2(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Stacktrace, InlineResolution) {
|
TEST(Stacktrace, InlineResolution) {
|
||||||
|
|||||||
@ -11,21 +11,24 @@
|
|||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
|
||||||
// NOTE: returning something and then return stacktrace_traced_object_3(line_numbers) * 2; later helps prevent the call from
|
// NOTE: returning something and then return stacktrace_multi_3(line_numbers) * rand(); is done to prevent TCO even
|
||||||
// being optimized to a jmp
|
// under LTO https://github.com/jeremy-rifkin/cpptrace/issues/179#issuecomment-2467302052
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_3(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_3(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
throw cpptrace::runtime_error("foobar");
|
throw cpptrace::runtime_error("foobar");
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_2(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_2(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_traced_object_3(line_numbers) * 2;
|
return stacktrace_traced_object_3(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_1(std::vector<int>& line_numbers) {
|
CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_1(std::vector<int>& line_numbers) {
|
||||||
|
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||||
return stacktrace_traced_object_2(line_numbers) * 2;
|
return stacktrace_traced_object_2(line_numbers) * rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TracedException, Basic) {
|
TEST(TracedException, Basic) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user