Factor out shared backtrace code (#1793)

This commit is contained in:
Rangi
2025-08-12 17:56:54 -04:00
committed by GitHub
parent 50d0b101c3
commit 9c3ce69180
14 changed files with 118 additions and 173 deletions

View File

@@ -51,6 +51,7 @@ set(rgbasm_src
"asm/symbol.cpp"
"asm/warning.cpp"
"extern/utf8decoder.cpp"
"backtrace.cpp"
"linkdefs.cpp"
"opmath.cpp"
"util.cpp"
@@ -72,6 +73,7 @@ set(rgblink_src
"link/symbol.cpp"
"link/warning.cpp"
"extern/utf8decoder.cpp"
"backtrace.cpp"
"linkdefs.cpp"
"opmath.cpp"
"util.cpp"

View File

@@ -11,11 +11,11 @@
#include <stdio.h>
#include <stdlib.h>
#include "backtrace.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "linkdefs.hpp"
#include "platform.hpp" // S_ISDIR (stat macro)
#include "style.hpp"
#include "verbosity.hpp"
#include "asm/lexer.hpp"
@@ -78,53 +78,12 @@ std::vector<std::pair<std::string, uint32_t>> FileStackNode::backtrace(uint32_t
}
}
static void printNode(std::pair<std::string, uint32_t> const &node) {
style_Set(stderr, STYLE_CYAN, true);
fputs(node.first.c_str(), stderr);
style_Set(stderr, STYLE_CYAN, false);
fprintf(stderr, "(%" PRIu32 ")", node.second);
}
void FileStackNode::printBacktrace(uint32_t curLineNo) const {
std::vector<std::pair<std::string, uint32_t>> nodes = backtrace(curLineNo);
size_t n = nodes.size();
if (warnings.traceDepth == TRACE_COLLAPSE) {
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
for (size_t i = 0; i < n; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printNode(nodes[n - i - 1]);
}
putc('\n', stderr);
} else if (warnings.traceDepth == 0 || static_cast<size_t>(warnings.traceDepth) >= n) {
for (size_t i = 0; i < n; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printNode(nodes[n - i - 1]);
putc('\n', stderr);
}
} else {
size_t last = warnings.traceDepth / 2;
size_t first = warnings.traceDepth - last;
size_t skipped = n - warnings.traceDepth;
for (size_t i = 0; i < first; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printNode(nodes[n - i - 1]);
putc('\n', stderr);
}
style_Reset(stderr);
fprintf(stderr, " ...%zu more%s\n", skipped, last ? "..." : "");
for (size_t i = n - last; i < n; ++i) {
style_Reset(stderr);
fputs(" <- ", stderr);
printNode(nodes[n - i - 1]);
putc('\n', stderr);
}
}
style_Reset(stderr);
trace_PrintBacktrace(
backtrace(curLineNo),
[](std::pair<std::string, uint32_t> const &node) { return node.first.c_str(); },
[](std::pair<std::string, uint32_t> const &node) { return node.second; }
);
}
void fstk_TraceCurrent() {

View File

@@ -11,6 +11,7 @@
#include <string.h>
#include <time.h>
#include "backtrace.hpp"
#include "diagnostics.hpp"
#include "extern/getopt.hpp"
#include "helpers.hpp"
@@ -303,23 +304,11 @@ int main(int argc, char *argv[]) {
switch (ch) {
char *endptr;
case 'B': {
if (!strcasecmp(musl_optarg, "collapse")) {
warnings.traceDepth = TRACE_COLLAPSE;
break;
}
warnings.traceDepth = strtoul(musl_optarg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') {
case 'B':
if (!trace_ParseTraceDepth(musl_optarg)) {
fatal("Invalid argument for option '-B'");
}
if (warnings.traceDepth >= UINT64_MAX) {
fatal("Argument for option '-B' is too large");
}
break;
}
case 'b':
if (strlen(musl_optarg) == 2) {

View File

@@ -60,7 +60,6 @@ Diagnostics<WarningLevel, WarningID> warnings = {
{WARNING_UNMAPPED_CHAR_1, WARNING_UNMAPPED_CHAR_2, 1},
},
.state = DiagnosticsState<WarningID>(),
.traceDepth = 0,
.nbErrors = 0,
};
// clang-format on

21
src/backtrace.cpp Normal file
View File

@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
#include "backtrace.hpp"
#include <stdlib.h> // strtoul
#include "platform.hpp" // strcasecmp
uint64_t traceDepth = 0;
bool trace_ParseTraceDepth(char const *arg) {
if (!strcasecmp(arg, "collapse")) {
traceDepth = TRACE_COLLAPSE;
return true;
}
char *endptr;
traceDepth = strtoul(arg, &endptr, 0);
return arg[0] != '\0' && *endptr == '\0' && traceDepth != TRACE_COLLAPSE;
}

View File

@@ -19,7 +19,6 @@ Diagnostics<WarningLevel, WarningID> warnings = {
},
.paramWarnings = {},
.state = DiagnosticsState<WarningID>(),
.traceDepth = 0,
.nbErrors = 0,
};
// clang-format on

View File

@@ -22,7 +22,6 @@ Diagnostics<WarningLevel, WarningID> warnings = {
},
.paramWarnings = {},
.state = DiagnosticsState<WarningID>(),
.traceDepth = 0,
.nbErrors = 0,
};
// clang-format on

View File

@@ -3,7 +3,7 @@
#include <inttypes.h>
#include <utility>
#include "style.hpp"
#include "backtrace.hpp"
#include "link/warning.hpp"
@@ -30,51 +30,10 @@ std::vector<std::pair<std::string, uint32_t>> FileStackNode::backtrace(uint32_t
}
}
static void printNode(std::pair<std::string, uint32_t> const &node) {
style_Set(stderr, STYLE_CYAN, true);
fputs(node.first.c_str(), stderr);
style_Set(stderr, STYLE_CYAN, false);
fprintf(stderr, "(%" PRIu32 ")", node.second);
}
void FileStackNode::printBacktrace(uint32_t curLineNo) const {
std::vector<std::pair<std::string, uint32_t>> nodes = backtrace(curLineNo);
size_t n = nodes.size();
if (warnings.traceDepth == TRACE_COLLAPSE) {
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
for (size_t i = 0; i < n; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printNode(nodes[n - i - 1]);
}
putc('\n', stderr);
} else if (warnings.traceDepth == 0 || static_cast<size_t>(warnings.traceDepth) >= n) {
for (size_t i = 0; i < n; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printNode(nodes[n - i - 1]);
putc('\n', stderr);
}
} else {
size_t last = warnings.traceDepth / 2;
size_t first = warnings.traceDepth - last;
size_t skipped = n - warnings.traceDepth;
for (size_t i = 0; i < first; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printNode(nodes[n - i - 1]);
putc('\n', stderr);
}
style_Reset(stderr);
fprintf(stderr, " ...%zu more%s\n", skipped, last ? "..." : "");
for (size_t i = n - last; i < n; ++i) {
style_Reset(stderr);
fputs(" <- ", stderr);
printNode(nodes[n - i - 1]);
putc('\n', stderr);
}
}
style_Reset(stderr);
trace_PrintBacktrace(
backtrace(curLineNo),
[](std::pair<std::string, uint32_t> const &node) { return node.first.c_str(); },
[](std::pair<std::string, uint32_t> const &node) { return node.second; }
);
}

View File

@@ -9,9 +9,9 @@
#include <stdio.h>
#include <vector>
#include "backtrace.hpp"
#include "helpers.hpp"
#include "itertools.hpp"
#include "style.hpp"
#include "util.hpp"
#include "link/warning.hpp"
@@ -28,52 +28,12 @@ struct LexerStackEntry {
static std::vector<LexerStackEntry> lexerStack;
static void printStackEntry(LexerStackEntry const &context) {
style_Set(stderr, STYLE_CYAN, true);
fputs(context.path.c_str(), stderr);
style_Set(stderr, STYLE_CYAN, false);
fprintf(stderr, "(%" PRIu32 ")", context.lineNo);
}
void lexer_TraceCurrent() {
size_t n = lexerStack.size();
if (warnings.traceDepth == TRACE_COLLAPSE) {
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
for (size_t i = 0; i < n; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printStackEntry(lexerStack[n - i - 1]);
}
putc('\n', stderr);
} else if (warnings.traceDepth == 0 || static_cast<size_t>(warnings.traceDepth) >= n) {
for (size_t i = 0; i < n; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printStackEntry(lexerStack[n - i - 1]);
putc('\n', stderr);
}
} else {
size_t last = warnings.traceDepth / 2;
size_t first = warnings.traceDepth - last;
size_t skipped = n - warnings.traceDepth;
for (size_t i = 0; i < first; ++i) {
style_Reset(stderr);
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
printStackEntry(lexerStack[n - i - 1]);
putc('\n', stderr);
}
style_Reset(stderr);
fprintf(stderr, " ...%zu more%s\n", skipped, last ? "..." : "");
for (size_t i = n - last; i < n; ++i) {
style_Reset(stderr);
fputs(" <- ", stderr);
printStackEntry(lexerStack[n - i - 1]);
putc('\n', stderr);
}
}
style_Reset(stderr);
trace_PrintBacktrace(
lexerStack,
[](LexerStackEntry const &context) { return context.path.c_str(); },
[](LexerStackEntry const &context) { return context.lineNo; }
);
}
void lexer_IncludeFile(std::string &&path) {

View File

@@ -10,6 +10,7 @@
#include <string.h>
#include <utility>
#include "backtrace.hpp"
#include "diagnostics.hpp"
#include "extern/getopt.hpp"
#include "helpers.hpp" // assume
@@ -295,21 +296,11 @@ int main(int argc, char *argv[]) {
// Parse options
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, nullptr)) != -1;) {
switch (ch) {
case 'B': {
if (!strcasecmp(musl_optarg, "collapse")) {
warnings.traceDepth = TRACE_COLLAPSE;
break;
}
char *endptr;
warnings.traceDepth = strtoul(musl_optarg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') {
case 'B':
if (!trace_ParseTraceDepth(musl_optarg)) {
fatal("Invalid argument for option '-B'");
}
if (warnings.traceDepth >= UINT64_MAX) {
fatal("Argument for option '-B' is too large");
}
break;
}
case 'd':
options.isDmgMode = true;
options.isWRAM0Mode = true;

View File

@@ -26,7 +26,6 @@ Diagnostics<WarningLevel, WarningID> warnings = {
},
.paramWarnings = {},
.state = DiagnosticsState<WarningID>(),
.traceDepth = 0,
.nbErrors = 0,
};
// clang-format on