1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#include <algorithm>
#include <array>
#include <cctype>
#include <iostream>
#include <string>
#include <vector>
#ifdef TEST_MODULE
import cpptrace;
#else
#include <cpptrace/cpptrace.hpp>
#endif
// preserve line numbers from when the integration test files were generated
#line 10
std::string normalize_filename(std::string name) {
if(name.find('/') == 0 || (name.find(':') == 1 && std::isupper(name[0]))) {
// build/integration if the file is really an object name resolved by libdl
auto p = std::min({name.rfind("test/"), name.rfind("test\\"), name.rfind("build/integration")});
return p == std::string::npos ? name : name.substr(p);
} else {
return name;
}
}
void custom_print(const cpptrace::stacktrace&);
void trace() {
auto trace = cpptrace::generate_trace();
if(trace.empty()) {
std::cerr << "<empty trace>" << std::endl;
}
custom_print(trace);
}
// padding to avoid upsetting existing trace expected files
void www(std::string&&, const std::string&, std::vector<std::string*>&&) {
trace();
}
void jjj(void(*const[5])(float)) {
www(std::string{}, "", {});
}
namespace Foo {
struct Bar {};
}
void iii(Foo::Bar) {
jjj(nullptr);
}
struct S {
int foo(float) const volatile && {
return 1;
}
};
void hhh(int(*(*)[10])[20]) {
iii(Foo::Bar{});
}
void ggg(const int * const *) {
hhh(nullptr);
}
void fff(int(S::*)(float) const volatile &&) {
ggg(nullptr);
}
//void eee(int(*(*(*)[10])())(float)) {
void eee(int(*(* const * volatile(*)[10])())(float)) {
fff(&S::foo);
}
void ddd(int(*(*)[10])()) {
eee(nullptr);
}
void ccc(int(*)[5][6][7][8]) {
ddd(nullptr);
}
void bbb(int(*const (&)[5])(float, const int&)) {
ccc(nullptr);
}
void aaa(int(&)[5]) {
int(*const (arr)[5])(float, const int&) = {};
bbb(arr);
}
int x;
void foo(int n) {
if(n == 0) {
x = 0;
int arr[5];
aaa(arr);
x = 0;
} else {
x = 0;
foo(n - 1);
x = 0;
}
}
template<typename... Args>
void foo(int, Args... args) {
x = 0;
foo(args...);
x = 0;
}
void function_two(int, float) {
x = 0;
foo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
x = 0;
}
void function_one(int) {
x = 0;
function_two(0, 0);
x = 0;
}
int main() {
x = 0;
cpptrace::absorb_trace_exceptions(false);
function_one(0);
x = 0;
}
void custom_print(const cpptrace::stacktrace& trace) {
for(const auto& frame : trace) {
std::cout
<< normalize_filename(frame.filename)
<< "||"
<< frame.line.value()
<< "||"
<< frame.symbol
<< std::endl;
}
}
|