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;
|
||||
|
||||
|
||||
// NOTE: returning something and then return stacktrace_from_current_3(line_numbers) * 2; later helps prevent the call from
|
||||
// being optimized to a jmp
|
||||
// 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 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);
|
||||
throw std::runtime_error("foobar");
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
|
||||
@ -13,27 +13,24 @@
|
||||
using namespace std::literals;
|
||||
|
||||
|
||||
// NOTE: returning something and then return stacktrace_from_current_3(line_numbers) * 2; later helps prevent the call from
|
||||
// being optimized to a jmp
|
||||
// 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 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
|
||||
[[maybe_unused]] volatile int x = 1;
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
line_numbers.insert(line_numbers.begin(), __LINE__ + 1);
|
||||
throw std::runtime_error("foobar");
|
||||
}
|
||||
|
||||
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
|
||||
[[maybe_unused]] volatile int x = 1;
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
// just here to differentiate from the non-z version to prevent ICF if LTO is being used
|
||||
[[maybe_unused]] volatile int x = 1;
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
@ -19,6 +20,7 @@ TEST(ObjectTrace, Empty) {
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void object_basic() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
auto trace = cpptrace::generate_object_trace();
|
||||
EXPECT_FALSE(trace.empty());
|
||||
EXPECT_NE(trace.frames[0].raw_address, 0);
|
||||
@ -33,6 +35,7 @@ TEST(ObjectTrace, Basic) {
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void object_basic_resolution() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
auto line = __LINE__ + 1;
|
||||
auto trace = cpptrace::generate_object_trace().resolve();
|
||||
ASSERT_GE(trace.frames.size(), 1);
|
||||
@ -49,6 +52,7 @@ TEST(ObjectTrace, BasicResolution) {
|
||||
// TODO: dbghelp uses raw address, not object
|
||||
#ifndef _MSC_VER
|
||||
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);
|
||||
auto dummy = cpptrace::generate_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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
|
||||
@ -18,6 +18,7 @@ using namespace std::literals;
|
||||
|
||||
// NOTE: MSVC likes creating trampoline-like entries for non-static functions
|
||||
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();
|
||||
// look for within 90 bytes of the start of the function
|
||||
ASSERT_GE(raw_trace.frames.size(), 1);
|
||||
@ -27,6 +28,7 @@ CPPTRACE_FORCE_NO_INLINE static void raw_trace_basic() {
|
||||
|
||||
#ifndef _MSC_VER
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_basic_precise() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
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_high_bound
|
||||
) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
ASSERT_GE(raw_trace.frames.size(), 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() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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);
|
||||
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;
|
||||
|
||||
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});
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_3() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
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() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
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() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
b:
|
||||
|
||||
@ -25,6 +25,7 @@ TEST(Stacktrace, Empty) {
|
||||
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE void stacktrace_basic() {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 1;
|
||||
auto line = __LINE__ + 1;
|
||||
auto trace = cpptrace::generate_trace();
|
||||
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
|
||||
// being optimized to a jmp
|
||||
// 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 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);
|
||||
auto trace = cpptrace::generate_trace();
|
||||
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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
@ -86,16 +90,19 @@ TEST(Stacktrace, MultipleFrames) {
|
||||
|
||||
|
||||
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);
|
||||
return cpptrace::generate_raw_trace();
|
||||
}
|
||||
|
||||
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);
|
||||
return stacktrace_raw_resolve_3(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);
|
||||
return stacktrace_raw_resolve_2(line_numbers);
|
||||
}
|
||||
@ -127,6 +134,7 @@ TEST(Stacktrace, RawTraceResolution) {
|
||||
|
||||
#ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF
|
||||
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);
|
||||
auto trace = cpptrace::generate_trace();
|
||||
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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
|
||||
@ -11,21 +11,24 @@
|
||||
using namespace std::literals;
|
||||
|
||||
|
||||
// NOTE: returning something and then return stacktrace_traced_object_3(line_numbers) * 2; later helps prevent the call from
|
||||
// being optimized to a jmp
|
||||
// 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 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);
|
||||
throw cpptrace::runtime_error("foobar");
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
static volatile int lto_guard; lto_guard = lto_guard + 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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user