-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f8ebdd2
commit 93b1d1c
Showing
4 changed files
with
140 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#include <algorithm> | ||
#include <iomanip> | ||
#include <sstream> | ||
#include <string_view> | ||
#include <string> | ||
|
||
#include <gtest/gtest.h> | ||
#include <gtest/gtest-matchers.h> | ||
#include <gmock/gmock.h> | ||
#include <gmock/gmock-matchers.h> | ||
#include <cpptrace/cpptrace.hpp> | ||
|
||
using namespace std::literals; | ||
|
||
// Raw trace tests | ||
|
||
// This is fickle, however, it's the only way to do it really. It's a reliable test in practice. | ||
|
||
[[gnu::noinline]] 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)); | ||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_basic) + 90); | ||
} | ||
|
||
#ifndef _MSC_VER | ||
[[gnu::noinline]] 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 | ||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&a)); | ||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&b)); | ||
} | ||
#endif | ||
|
||
TEST(RawTrace, Basic) { | ||
raw_trace_basic(); | ||
raw_trace_basic_precise(); | ||
} | ||
|
||
[[gnu::noinline]] void raw_trace_multi_1(std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr> parent) { | ||
auto raw_trace = cpptrace::generate_raw_trace(); | ||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_1)); | ||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_1) + 90); | ||
EXPECT_GE(raw_trace.frames[1], parent.first); | ||
EXPECT_LE(raw_trace.frames[1], parent.second); | ||
} | ||
|
||
[[gnu::noinline]] void raw_trace_multi_top() { | ||
auto raw_trace = cpptrace::generate_raw_trace(); | ||
raw_trace_multi_1({reinterpret_cast<uintptr_t>(raw_trace_multi_top), reinterpret_cast<uintptr_t>(raw_trace_multi_top) + 300}); | ||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_top)); | ||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_multi_top) + 90); | ||
} | ||
|
||
#ifndef _MSC_VER | ||
[[gnu::noinline]] void raw_trace_multi_precise_2(std::vector<std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr>>& parents) { | ||
a: | ||
auto raw_trace = cpptrace::generate_raw_trace(); | ||
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 | ||
EXPECT_GE(raw_trace.frames[i + 1], parents[i].first); | ||
EXPECT_LE(raw_trace.frames[i + 1], parents[i].second); | ||
} | ||
} | ||
|
||
[[gnu::noinline]] void raw_trace_multi_precise_1(std::vector<std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr>>& parents) { | ||
a: | ||
auto raw_trace = cpptrace::generate_raw_trace(); | ||
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 | ||
EXPECT_GE(raw_trace.frames[i + 1], parents[i].first); | ||
EXPECT_LE(raw_trace.frames[i + 1], parents[i].second); | ||
} | ||
parents.insert(parents.begin(), {reinterpret_cast<uintptr_t>(&&c), reinterpret_cast<uintptr_t>(&&d)}); | ||
c: | ||
raw_trace_multi_precise_2(parents); | ||
d:; | ||
} | ||
|
||
[[gnu::noinline]] void raw_trace_multi_precise_top() { | ||
a: | ||
auto raw_trace = cpptrace::generate_raw_trace(); | ||
b: | ||
EXPECT_GE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&a)); | ||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(&&b)); | ||
std::vector<std::pair<cpptrace::frame_ptr, cpptrace::frame_ptr>> parents; | ||
parents.insert(parents.begin(), {reinterpret_cast<uintptr_t>(&&c), reinterpret_cast<uintptr_t>(&&d)}); | ||
c: | ||
raw_trace_multi_precise_1(parents); | ||
d:; | ||
} | ||
#endif | ||
|
||
TEST(RawTrace, MultipleCalls) { | ||
raw_trace_multi_top(); | ||
raw_trace_multi_precise_top(); | ||
} | ||
|
||
[[gnu::noinline]] void stacktrace_basic() { | ||
auto line = __LINE__ + 1; | ||
auto trace = cpptrace::generate_trace(); | ||
EXPECT_THAT(trace.frames[0].filename, testing::EndsWith("unittest.cpp")); | ||
EXPECT_EQ(trace.frames[0].line.value(), line); | ||
EXPECT_THAT(trace.frames[0].symbol, testing::HasSubstr("stacktrace_basic")); | ||
} | ||
|
||
TEST(Stacktrace, Basic) { | ||
stacktrace_basic(); | ||
} |