Add some test failure reporting stuff and fix a bug in test cases (#45)
This commit is contained in:
parent
76fc93639e
commit
1c3e0e92f4
@ -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",
|
||||||
],
|
],
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
96
ci/util.py
96
ci/util.py
@ -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)
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
39
test/expected/windows.gcc.txt
Normal file
39
test/expected/windows.gcc.txt
Normal 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
|
||||||
@ -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()
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user