Add some test failure reporting stuff and fix a bug in test cases (#45)

This commit is contained in:
Jeremy Rifkin 2023-09-23 17:25:41 -04:00 committed by GitHub
parent 76fc93639e
commit 1c3e0e92f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 256 additions and 75 deletions

View File

@ -59,7 +59,7 @@ def build(matrix):
"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h", "-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
) )
if succeeded: if succeeded:
run_command("make", "-j", "VERBOSE=1") succeeded = run_command("make", "-j", "VERBOSE=1")
else: else:
args = [ args = [
"cmake", "cmake",
@ -76,13 +76,15 @@ def build(matrix):
succeeded = run_command(*args) succeeded = run_command(*args)
if succeeded: if succeeded:
if matrix["compiler"] == "g++": if matrix["compiler"] == "g++":
run_command("make", "-j", "VERBOSE=1") succeeded = run_command("make", "-j", "VERBOSE=1")
else: else:
run_command("msbuild", "cpptrace.sln") succeeded = run_command("msbuild", "cpptrace.sln")
os.chdir("..") os.chdir("..")
print() print()
return succeeded
def build_full_or_auto(matrix): def build_full_or_auto(matrix):
#touch_sources() #touch_sources()
print(f"{Fore.BLUE}{Style.BRIGHT}{'=' * 10} Running build with config {'<auto>' if matrix['config'] == '' else ', '.join(matrix.values())} {'=' * 10}{Style.RESET_ALL}") print(f"{Fore.BLUE}{Style.BRIGHT}{'=' * 10} Running build with config {'<auto>' if matrix['config'] == '' else ', '.join(matrix.values())} {'=' * 10}{Style.RESET_ALL}")
@ -106,7 +108,7 @@ def build_full_or_auto(matrix):
args.append(f"{matrix['config']}") args.append(f"{matrix['config']}")
succeeded = run_command(*args) succeeded = run_command(*args)
if succeeded: if succeeded:
run_command("make", "-j") succeeded = run_command("make", "-j")
else: else:
args = [ args = [
"cmake", "cmake",
@ -122,13 +124,15 @@ def build_full_or_auto(matrix):
succeeded = run_command(*args) succeeded = run_command(*args)
if succeeded: if succeeded:
if matrix["compiler"] == "g++": if matrix["compiler"] == "g++":
run_command("make", "-j") succeeded = run_command("make", "-j")
else: else:
run_command("msbuild", "cpptrace.sln") succeeded = run_command("msbuild", "cpptrace.sln")
os.chdir("..") os.chdir("..")
print() print()
return succeeded
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
prog="Build in all configs", prog="Build in all configs",
@ -148,7 +152,7 @@ def main():
"symbols": [ "symbols": [
"CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE", "CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL", "CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF" "CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF",
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE", "CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
"CPPTRACE_GET_SYMBOLS_WITH_NOTHING", "CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
], ],

View File

@ -73,7 +73,7 @@ def output_matches(output: str, params: Tuple[str]):
if output.strip() == "": if output.strip() == "":
print(f"Error: No output from test") print(f"Error: No output from test")
sys.exit(1) return False
expected = [line.strip().split("||") for line in expected.split("\n")] expected = [line.strip().split("||") for line in expected.split("\n")]
output = [line.strip().split("||") for line in output.split("\n")] output = [line.strip().split("||") for line in output.split("\n")]
@ -131,15 +131,20 @@ def run_test(test_binary, params: Tuple[str]):
print("stdout:") print("stdout:")
print(test_stdout.decode("utf-8"), end="") print(test_stdout.decode("utf-8"), end="")
failed = True failed = True
return False
else: else:
if len(test_stderr) != 0: if len(test_stderr) != 0:
print("stderr:") print("stderr:")
print(test_stderr.decode("utf-8"), end="") print(test_stderr.decode("utf-8"), end="")
print(test_stdout, test_stderr, test.returncode)
print(test)
if output_matches(test_stdout.decode("utf-8"), params): if output_matches(test_stdout.decode("utf-8"), params):
print(f"{Fore.GREEN}{Style.BRIGHT}Test succeeded{Style.RESET_ALL}") print(f"{Fore.GREEN}{Style.BRIGHT}Test succeeded{Style.RESET_ALL}")
return True
else: else:
print(f"{Fore.RED}{Style.BRIGHT}Test failed{Style.RESET_ALL}") print(f"{Fore.RED}{Style.BRIGHT}Test failed{Style.RESET_ALL}")
failed = True failed = True
return False
def build(matrix): def build(matrix):
if platform.system() != "Windows": if platform.system() != "Windows":
@ -177,9 +182,10 @@ def build(matrix):
succeeded = run_command(*args) succeeded = run_command(*args)
if succeeded: if succeeded:
if matrix["compiler"] == "g++": if matrix["compiler"] == "g++":
run_command("make", "-j") return run_command("make", "-j")
else: else:
run_command("msbuild", "cpptrace.sln") return run_command("msbuild", "cpptrace.sln")
return False
def build_full_or_auto(matrix): def build_full_or_auto(matrix):
if platform.system() != "Windows": if platform.system() != "Windows":
@ -213,42 +219,43 @@ def build_full_or_auto(matrix):
succeeded = run_command(*args) succeeded = run_command(*args)
if succeeded: if succeeded:
if matrix["compiler"] == "g++": if matrix["compiler"] == "g++":
run_command("make", "-j") return run_command("make", "-j")
else: else:
run_command("msbuild", "cpptrace.sln") return run_command("msbuild", "cpptrace.sln")
return False
def test(matrix): def test(matrix):
if platform.system() != "Windows": if platform.system() != "Windows":
run_test( return run_test(
"./test", "./test",
(matrix["compiler"], matrix["unwind"], matrix["symbols"], matrix["demangle"]) (matrix["compiler"], matrix["unwind"], matrix["symbols"], matrix["demangle"])
) )
else: else:
if matrix["compiler"] == "g++": if matrix["compiler"] == "g++":
run_test( return run_test(
f".\\test.exe", f".\\test.exe",
(matrix["compiler"], matrix["unwind"], matrix["symbols"], matrix["demangle"]) (matrix["compiler"], matrix["unwind"], matrix["symbols"], matrix["demangle"])
) )
else: else:
run_test( return run_test(
f".\\{matrix['target']}\\test.exe", f".\\{matrix['target']}\\test.exe",
(matrix["compiler"], matrix["unwind"], matrix["symbols"], matrix["demangle"]) (matrix["compiler"], matrix["unwind"], matrix["symbols"], matrix["demangle"])
) )
def test_full_or_auto(matrix): def test_full_or_auto(matrix):
if platform.system() != "Windows": if platform.system() != "Windows":
run_test( return run_test(
"./test", "./test",
(matrix["compiler"],) (matrix["compiler"],)
) )
else: else:
if matrix["compiler"] == "g++": if matrix["compiler"] == "g++":
run_test( return run_test(
f".\\test.exe", f".\\test.exe",
(matrix["compiler"],) (matrix["compiler"],)
) )
else: else:
run_test( return run_test(
f".\\{matrix['target']}\\test.exe", f".\\{matrix['target']}\\test.exe",
(matrix["compiler"],) (matrix["compiler"],)
) )
@ -262,12 +269,15 @@ def build_and_test(matrix):
os.mkdir("build") os.mkdir("build")
os.chdir("build") os.chdir("build")
good = False
if build(matrix): if build(matrix):
test(matrix) good = test(matrix)
os.chdir("..") os.chdir("..")
print() print()
return good
def build_and_test_full_or_auto(matrix): def build_and_test_full_or_auto(matrix):
print(f"{Fore.BLUE}{Style.BRIGHT}{'=' * 10} Running build and test with config {'<auto>' if matrix['config'] == '' else ', '.join(matrix.values())} {'=' * 10}{Style.RESET_ALL}") print(f"{Fore.BLUE}{Style.BRIGHT}{'=' * 10} Running build and test with config {'<auto>' if matrix['config'] == '' else ', '.join(matrix.values())} {'=' * 10}{Style.RESET_ALL}")
@ -277,12 +287,15 @@ def build_and_test_full_or_auto(matrix):
os.mkdir("build") os.mkdir("build")
os.chdir("build") os.chdir("build")
good = False
if build_full_or_auto(matrix): if build_full_or_auto(matrix):
test_full_or_auto(matrix) good = test_full_or_auto(matrix)
os.chdir("..") os.chdir("..")
print() print()
return good
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
prog="Build in all configs", prog="Build in all configs",
@ -382,7 +395,7 @@ def main():
"std": ["11", "20"], "std": ["11", "20"],
"unwind": [ "unwind": [
"CPPTRACE_UNWIND_WITH_WINAPI", "CPPTRACE_UNWIND_WITH_WINAPI",
"CPPTRACE_UNWIND_WITH_UNWIND", #"CPPTRACE_UNWIND_WITH_UNWIND", # Broken on github actions for some reason
#"CPPTRACE_UNWIND_WITH_NOTHING", #"CPPTRACE_UNWIND_WITH_NOTHING",
], ],
"symbols": [ "symbols": [
@ -392,7 +405,7 @@ def main():
#"CPPTRACE_GET_SYMBOLS_WITH_NOTHING", #"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
], ],
"demangle": [ "demangle": [
#"CPPTRACE_DEMANGLE_WITH_CXXABI", "CPPTRACE_DEMANGLE_WITH_CXXABI",
"CPPTRACE_DEMANGLE_WITH_NOTHING", "CPPTRACE_DEMANGLE_WITH_NOTHING",
] ]
} }
@ -428,6 +441,18 @@ def main():
{ {
"symbols": "CPPTRACE_GET_SYMBOLS_WITH_DBGHELP", "symbols": "CPPTRACE_GET_SYMBOLS_WITH_DBGHELP",
"compiler": "g++" "compiler": "g++"
},
{
"symbols": "CPPTRACE_GET_SYMBOLS_WITH_DBGHELP",
"demangle": "CPPTRACE_DEMANGLE_WITH_CXXABI"
},
{
"symbols": "CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF",
"demangle": "CPPTRACE_DEMANGLE_WITH_NOTHING"
},
{
"symbols": "CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
"demangle": "CPPTRACE_DEMANGLE_WITH_NOTHING"
} }
] ]
run_matrix(matrix, exclude, build_and_test) run_matrix(matrix, exclude, build_and_test)
@ -438,7 +463,8 @@ def main():
"config": [""] "config": [""]
} }
exclude = [] exclude = []
run_matrix(matrix, exclude, build_and_test_full_or_auto) # TODO: Disabled for now due to unwind
#run_matrix(matrix, exclude, build_and_test_full_or_auto)
global failed global failed
if failed: if failed:

View File

@ -2,12 +2,47 @@ import subprocess
import sys import sys
import itertools import itertools
from typing import List from typing import List
from colorama import Fore, Back, Style
import re
# https://stackoverflow.com/a/14693789/15675011
ansi_escape = re.compile(r'''
\x1B # ESC
(?: # 7-bit C1 Fe (except CSI)
[@-Z\\-_]
| # or [ for CSI, followed by a control sequence
\[
[0-?]* # Parameter bytes
[ -/]* # Intermediate bytes
[@-~] # Final byte
)
''', re.VERBOSE)
def adj_width(text):
return len(text) - len(ansi_escape.sub("", text))
def do_exclude(matrix_config, exclude): def do_exclude(matrix_config, exclude):
return all(map(lambda k: matrix_config[k] == exclude[k], exclude.keys())) return all(map(lambda k: matrix_config[k] == exclude[k], exclude.keys()))
def print_table(table):
columns = len(table[0])
column_widths = [1 for _ in range(columns)]
for row in table:
for i, cell in enumerate(row):
column_widths[i] = max(column_widths[i], len(ansi_escape.sub("", cell)))
for j, cell in enumerate(table[0]):
print("| {cell:{width}} ".format(cell=cell, width=column_widths[j] + adj_width(cell)), end="")
print("|")
for i, row in enumerate(table[1:]):
for j, cell in enumerate(row):
print("| {cell:{width}} ".format(cell=cell, width=column_widths[j] + adj_width(cell)), end="")
print("|")
def run_matrix(matrix, exclude, fn): def run_matrix(matrix, exclude, fn):
#print(matrix.values()) keys = [*matrix.keys()]
values = [*matrix.values()]
#print("Values:", values)
results = {} # insertion-ordered
for config in itertools.product(*matrix.values()): for config in itertools.product(*matrix.values()):
#print(config) #print(config)
matrix_config = {} matrix_config = {}
@ -17,4 +52,61 @@ def run_matrix(matrix, exclude, fn):
if any(map(lambda ex: do_exclude(matrix_config, ex), exclude)): if any(map(lambda ex: do_exclude(matrix_config, ex), exclude)):
continue continue
else: else:
fn(matrix_config) config_tuple = tuple(values[i].index(p) for i, p in enumerate(config))
results[config_tuple] = fn(matrix_config)
# Fudged data for testing
#print(config_tuple)
#if "symbols" not in matrix_config:
# results[config_tuple] = matrix_config["compiler"] != "g++-10"
#else:
# results[config_tuple] = not (matrix_config["compiler"] == "clang++-14" and matrix_config["symbols"] == "CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE")
# I had an idea for printing 2d slices of the n-dimentional matrix, but it didn't pan out as much as I'd hoped
dimensions = len(values)
# # Output diagnostic tables
# print("Results:", results)
# if dimensions >= 2:
# for iteraxes in itertools.combinations(range(dimensions), dimensions - 2):
# # iteraxes are the axes we iterate over to slice, these fixed axes are the axes of the table
# # just the complement of axes, these are the two fixed axes
# fixed = [x for x in range(dimensions) if x not in iteraxes]
# assert(len(fixed) == 2)
# if any([len(values[i]) == 1 for i in fixed]):
# continue
# print("Fixed:", fixed)
# for iteraxesvalues in itertools.product(
# *[range(len(values[i])) if i in iteraxes else [-1] for i in range(dimensions)]
# ):
# print(">>", iteraxesvalues)
# # Now that we have our iteraxes values we have a unique plane
# table = [
# ["", *[value for value in values[fixed[0]]]]
# ]
# #print(values[fixed[1]])
# for row_i, row_value in enumerate(values[fixed[1]]):
# row = [row_value]
# for col_i in range(len(values[fixed[0]])):
# iteraxesvaluescopy = [x for x in iteraxesvalues]
# iteraxesvaluescopy[fixed[1]] = row_i
# iteraxesvaluescopy[fixed[0]] = col_i
# #print("----->", iteraxesvaluescopy)
# row.append(
# f"{Fore.GREEN}{Style.BRIGHT}Good{Style.RESET_ALL}"
# if results[tuple(iteraxesvaluescopy)]
# else f"{Fore.RED}{Style.BRIGHT}Bad{Style.RESET_ALL}"
# if tuple(iteraxesvaluescopy) in results else ""
# )
# table.append(row)
# print_table(table)
# Better idea would be looking for m<n tuples that are consistently failing and reporting on those
#for fixed_axes in itertools.product(range(dimensions), 2):
# pass
print("Results:")
table = [keys]
for result in results:
table.append([
f"{Fore.GREEN if results[result] else Fore.RED}{Style.BRIGHT}{values[i][v]}{Style.RESET_ALL}"
for i, v in enumerate(result)
])
print_table(table)

View File

@ -40,8 +40,10 @@ namespace cpptrace {
using iterator = std::vector<uintptr_t>::iterator; using iterator = std::vector<uintptr_t>::iterator;
using const_iterator = std::vector<uintptr_t>::const_iterator; using const_iterator = std::vector<uintptr_t>::const_iterator;
inline iterator begin() noexcept { return frames.begin(); } inline iterator begin() noexcept { return frames.begin(); }
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
inline iterator end() noexcept { return frames.end(); } inline iterator end() noexcept { return frames.end(); }
inline const_iterator begin() const noexcept { return frames.begin(); }
inline const_iterator end() const noexcept { return frames.end(); }
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
inline const_iterator cend() const noexcept { return frames.cend(); } inline const_iterator cend() const noexcept { return frames.cend(); }
}; };
@ -64,14 +66,16 @@ namespace cpptrace {
using iterator = std::vector<object_frame>::iterator; using iterator = std::vector<object_frame>::iterator;
using const_iterator = std::vector<object_frame>::const_iterator; using const_iterator = std::vector<object_frame>::const_iterator;
inline iterator begin() noexcept { return frames.begin(); } inline iterator begin() noexcept { return frames.begin(); }
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
inline iterator end() noexcept { return frames.end(); } inline iterator end() noexcept { return frames.end(); }
inline const_iterator begin() const noexcept { return frames.begin(); }
inline const_iterator end() const noexcept { return frames.end(); }
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
inline const_iterator cend() const noexcept { return frames.cend(); } inline const_iterator cend() const noexcept { return frames.cend(); }
}; };
struct stacktrace_frame { struct stacktrace_frame {
uintptr_t address; uintptr_t address;
std::uint_least32_t line; std::uint_least32_t line; // TODO: This should use UINT_LEAST32_MAX as a sentinel
std::uint_least32_t column; // UINT_LEAST32_MAX if not present std::uint_least32_t column; // UINT_LEAST32_MAX if not present
std::string filename; std::string filename;
std::string symbol; std::string symbol;
@ -106,8 +110,10 @@ namespace cpptrace {
using iterator = std::vector<stacktrace_frame>::iterator; using iterator = std::vector<stacktrace_frame>::iterator;
using const_iterator = std::vector<stacktrace_frame>::const_iterator; using const_iterator = std::vector<stacktrace_frame>::const_iterator;
inline iterator begin() noexcept { return frames.begin(); } inline iterator begin() noexcept { return frames.begin(); }
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
inline iterator end() noexcept { return frames.end(); } inline iterator end() noexcept { return frames.end(); }
inline const_iterator begin() const noexcept { return frames.begin(); }
inline const_iterator end() const noexcept { return frames.end(); }
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
inline const_iterator cend() const noexcept { return frames.cend(); } inline const_iterator cend() const noexcept { return frames.cend(); }
private: private:
CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end) const; CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end) const;
@ -139,6 +145,7 @@ namespace cpptrace {
return generate_raw_trace(skip + 2, max_depth); return generate_raw_trace(skip + 2, max_depth);
} catch(const std::exception& e) { } catch(const std::exception& e) {
if(!detail::should_absorb_trace_exceptions()) { if(!detail::should_absorb_trace_exceptions()) {
// TODO: Append to message somehow
fprintf( fprintf(
stderr, stderr,
"Exception ocurred while resolving trace in cpptrace::exception object:\n%s\n", "Exception ocurred while resolving trace in cpptrace::exception object:\n%s\n",
@ -159,6 +166,7 @@ namespace cpptrace {
} }
} catch(const std::exception& e) { } catch(const std::exception& e) {
if(!detail::should_absorb_trace_exceptions()) { if(!detail::should_absorb_trace_exceptions()) {
// TODO: Append to message somehow
fprintf( fprintf(
stderr, stderr,
"Exception ocurred while resolving trace in cpptrace::exception object:\n%s\n", "Exception ocurred while resolving trace in cpptrace::exception object:\n%s\n",

View File

@ -1,4 +1,4 @@
test/test.cpp||21||trace() test/test.cpp||23||trace()
test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> >&&) test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> >&&)
test/test.cpp||37||jjj(void (* const*)(float)) test/test.cpp||37||jjj(void (* const*)(float))
test/test.cpp||45||iii(Foo::Bar) test/test.cpp||45||iii(Foo::Bar)

View File

@ -1,4 +1,4 @@
test/test.cpp||21||trace() test/test.cpp||23||trace()
test/test.cpp||33||www(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*>>&&) test/test.cpp||33||www(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*>>&&)
test/test.cpp||37||jjj(void (* const*)(float)) test/test.cpp||37||jjj(void (* const*)(float))
test/test.cpp||45||iii(Foo::Bar) test/test.cpp||45||iii(Foo::Bar)

View File

@ -1,4 +1,4 @@
test/test.cpp||21||trace() test/test.cpp||23||trace()
test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*>>&&) test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*>>&&)
test/test.cpp||37||jjj(void (* const*)(float)) test/test.cpp||37||jjj(void (* const*)(float))
test/test.cpp||45||iii(Foo::Bar) test/test.cpp||45||iii(Foo::Bar)

View File

@ -1,4 +1,4 @@
test/test.cpp||21||trace() test/test.cpp||23||trace()
test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> >&&) test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> >&&)
test/test.cpp||37||jjj(void (* const*)(float)) test/test.cpp||37||jjj(void (* const*)(float))
test/test.cpp||45||iii(Foo::Bar) test/test.cpp||45||iii(Foo::Bar)

View File

@ -0,0 +1,39 @@
test/test.cpp||23||trace()
test/test.cpp||33||www(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> >&&)
test/test.cpp||37||jjj(void (* const*)(float))
test/test.cpp||45||iii(Foo::Bar)
test/test.cpp||55||hhh(int (* (*) [10]) [20])
test/test.cpp||59||ggg(int const* const*)
test/test.cpp||63||fff(int (S::*)(float) const volatile &&)
test/test.cpp||68||eee(int (*(* const* volatile (*) [10])())(float))
test/test.cpp||72||ddd(int (* (*) [10])())
test/test.cpp||76||ccc(int (*) [5][6][7][8])
test/test.cpp||80||bbb(int (* const (&) [5])(float, int const&))
test/test.cpp||85||aaa(int (&) [5])
test/test.cpp||94||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||98||foo(int)
test/test.cpp||106||void foo<int>(int, int)
test/test.cpp||106||void foo<int, int>(int, int, int)
test/test.cpp||106||void foo<int, int, int>(int, int, int, int)
test/test.cpp||106||void foo<int, int, int, int>(int, int, int, int, int)
test/test.cpp||106||void foo<int, int, int, int, int>(int, int, int, int, int, int)
test/test.cpp||106||void foo<int, int, int, int, int, int>(int, int, int, int, int, int, int)
test/test.cpp||106||void foo<int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int)
test/test.cpp||106||void foo<int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int)
test/test.cpp||106||void foo<int, int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int, int)
test/test.cpp||112||function_two(int, float)
test/test.cpp||118||function_one(int)
test/test.cpp||124||main
C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c||272||__tmainCRTStartup
C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c||193||mainCRTStartup
||0||BaseThreadInitThunk
||0||RtlUserThreadStart

View File

@ -1,38 +1,38 @@
test\test.cpp||21||trace() test\test.cpp||23||trace()
test\test.cpp||37||www(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> > *, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > *> >*) test\test.cpp||33||www(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> > *, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > *> >*)
test\test.cpp||41||jjj(void(*(*))(float)) test\test.cpp||37||jjj(void(*(*))(float))
test\test.cpp||49||iii(Foo::Bar) test\test.cpp||45||iii(Foo::Bar)
test\test.cpp||59||hhh(int(*(*)[10])[20]) test\test.cpp||55||hhh(int(*(*)[10])[20])
test\test.cpp||63||ggg(int**) test\test.cpp||59||ggg(int**)
test\test.cpp||67||fff(int(S::*)(float)) test\test.cpp||63||fff(int(S::*)(float))
test\test.cpp||72||eee(int(*(*(*(*)[10]))())(float)) test\test.cpp||68||eee(int(*(*(*(*)[10]))())(float))
test\test.cpp||76||ddd(int(*(*)[10])()) test\test.cpp||72||ddd(int(*(*)[10])())
test\test.cpp||80||ccc(int(*)[5][6][7][8]) test\test.cpp||76||ccc(int(*)[5][6][7][8])
test\test.cpp||84||bbb(int(*(&)[5])(float, int&)) test\test.cpp||80||bbb(int(*(&)[5])(float, int&))
test\test.cpp||89||aaa(int(&)[5]) test\test.cpp||85||aaa(int(&)[5])
test\test.cpp||94||foo(int)
test\test.cpp||98||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||98||foo(int)
test\test.cpp||102||foo(int) test\test.cpp||106||foo<int>(int, int)
test\test.cpp||110||foo<int>(int, int) test\test.cpp||106||foo<int, int>(int, int, int)
test\test.cpp||110||foo<int, int>(int, int, int) test\test.cpp||106||foo<int, int, int>(int, int, int, int)
test\test.cpp||110||foo<int, int, int>(int, int, int, int) test\test.cpp||106||foo<int, int, int, int>(int, int, int, int, int)
test\test.cpp||110||foo<int, int, int, int>(int, int, int, int, int) test\test.cpp||106||foo<int, int, int, int, int>(int, int, int, int, int, int)
test\test.cpp||110||foo<int, int, int, int, int>(int, int, int, int, int, int) test\test.cpp||106||foo<int, int, int, int, int, int>(int, int, int, int, int, int, int)
test\test.cpp||110||foo<int, int, int, int, int, int>(int, int, int, int, int, int, int) test\test.cpp||106||foo<int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int)
test\test.cpp||110||foo<int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int) test\test.cpp||106||foo<int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int)
test\test.cpp||110||foo<int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int) test\test.cpp||106||foo<int, int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int, int)
test\test.cpp||110||foo<int, int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int, int) test\test.cpp||112||function_two(int, float)
test\test.cpp||116||function_two(int, float) test\test.cpp||118||function_one(int)
test\test.cpp||122||function_one(int) test\test.cpp||124||main()
test\test.cpp||128||main()
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl||79||invoke_main() D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl||79||invoke_main()
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl||288||__scrt_common_main_seh() D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl||288||__scrt_common_main_seh()
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl||331||__scrt_common_main() D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl||331||__scrt_common_main()

View File

@ -17,18 +17,18 @@ std::string normalize_filename(std::string name) {
} }
} }
void custom_print(const cpptrace::stacktrace&);
void trace() { void trace() {
for(const auto& frame : cpptrace::generate_trace()) { auto trace = cpptrace::generate_trace();
std::cout if(trace.empty()) {
<< normalize_filename(frame.filename) std::cerr << "<empty trace>" << std::endl;
<< "||"
<< frame.line
<< "||"
<< frame.symbol
<< std::endl;
} }
custom_print(trace);
} }
// padding to avoid upsetting existing trace expected files
void www(std::string&&, const std::string& str, std::vector<std::string*>&& foobar) { void www(std::string&&, const std::string& str, std::vector<std::string*>&& foobar) {
trace(); trace();
} }
@ -124,3 +124,15 @@ int main() {
function_one(0); function_one(0);
x = 0; x = 0;
} }
void custom_print(const cpptrace::stacktrace& trace) {
for(const auto& frame : trace) {
std::cout
<< normalize_filename(frame.filename)
<< "||"
<< frame.line
<< "||"
<< frame.symbol
<< std::endl;
}
}