#include #include #include #include #include #include #include #include #include #include using namespace std::literals; TEST(ObjectTrace, Empty) { cpptrace::object_trace empty; EXPECT_TRUE(empty.empty()); EXPECT_EQ(empty.resolve().to_string(), "Stack trace (most recent call first):\n\n"); } CPPTRACE_FORCE_NO_INLINE void object_basic() { auto trace = cpptrace::generate_object_trace(); EXPECT_FALSE(trace.empty()); EXPECT_NE(trace.frames[0].raw_address, 0); EXPECT_NE(trace.frames[0].object_address, 0); EXPECT_THAT(trace.frames[0].object_path, testing::HasSubstr("unittest")); } TEST(ObjectTrace, Basic) { object_basic(); } CPPTRACE_FORCE_NO_INLINE void object_basic_resolution() { auto line = __LINE__ + 1; auto trace = cpptrace::generate_object_trace().resolve(); EXPECT_THAT(trace.frames[0].filename, testing::EndsWith("object_trace.cpp")); EXPECT_EQ(trace.frames[0].line.value(), line); EXPECT_THAT(trace.frames[0].symbol, testing::HasSubstr("object_basic_resolution")); } TEST(ObjectTrace, BasicResolution) { object_basic(); } CPPTRACE_FORCE_NO_INLINE void object_resolve_3(std::vector& 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}); auto trace = otrace.resolve(); int i = 0; 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("object_resolve_3")); i++; 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("object_resolve_2")); i++; 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("object_resolve_1")); i++; 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")); } CPPTRACE_FORCE_NO_INLINE void object_resolve_2(std::vector& line_numbers) { line_numbers.insert(line_numbers.begin(), __LINE__ + 1); object_resolve_3(line_numbers); } CPPTRACE_FORCE_NO_INLINE void object_resolve_1(std::vector& line_numbers) { line_numbers.insert(line_numbers.begin(), __LINE__ + 1); object_resolve_2(line_numbers); } TEST(ObjectTrace, Resolution) { std::vector line_numbers; line_numbers.insert(line_numbers.begin(), __LINE__ + 1); object_resolve_1(line_numbers); }