aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/log.cc
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-04-24 19:37:47 +0000
committerwhitequark <whitequark@whitequark.org>2020-05-03 12:02:34 +0000
commite9f2d3f009d0c9da59758a6e14cddf1cebae1f59 (patch)
tree85614baea1761b9f10ea70bd84eb4a07cb2ab473 /kernel/log.cc
parentcf14e186eb6c89696cd1db4b36697a4e80b6884a (diff)
downloadyosys-e9f2d3f009d0c9da59758a6e14cddf1cebae1f59.tar.gz
yosys-e9f2d3f009d0c9da59758a6e14cddf1cebae1f59.tar.bz2
yosys-e9f2d3f009d0c9da59758a6e14cddf1cebae1f59.zip
kernel: Trap in `log_error()` when a debugger is attached.
The workflow of debugging fatal pass errors in Yosys is flawed in three ways: 1. Running Yosys under a debugger is sufficient for the debugger to catch some fatal errors (segfaults, aborts, STL exceptions) but not others (`log_error()`, `log_cmd_error()`). This is neither obvious nor easy to remember. 2. To catch Yosys-specific fatal errors, it is necessary to set a breakpoint at `logv_error_with_prefix()`, or at least, `logv_error()`. This is neither obvious nor easy to remember, and GDB's autocomplete takes many seconds to suggest function names due to the large amount of symbols in Yosys. 3. If a breakpoint is not set and Yosys encounters with such a fatal error, the process terminates. When debugging a crash that takes a long time to reproduce (or a nondeterministic crash) this can waste a significant amount of time. To solve this problem, add a macro `YS_DEBUGTRAP` that acts as a hard breakpoint (if available), and a macro `YS_DEBUGTRAP_IF_DEBUGGING` that acts as a hard breakpoint only if debugger is present. Then, use `YS_DEBUGTRAP_IF_DEBUGGING` in `logv_error_with_prefix()` to obviate the need for a breakpoint on nearly every platform. Co-Authored-By: Alberto Gonzalez <boqwxp@airmail.cc>
Diffstat (limited to 'kernel/log.cc')
-rw-r--r--kernel/log.cc7
1 files changed, 5 insertions, 2 deletions
diff --git a/kernel/log.cc b/kernel/log.cc
index d84a4381e..a21ba480a 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -354,6 +354,9 @@ static void logv_error_with_prefix(const char *prefix,
if (check_expected_logs)
log_check_expected();
+
+ YS_DEBUGTRAP_IF_DEBUGGING;
+
#ifdef EMSCRIPTEN
log_files = backup_log_files;
throw 0;
@@ -673,7 +676,7 @@ void log_check_expected()
}
if (item.second.current_count != item.second.expected_count) {
log_warn_regexes.clear();
- log_error("Expected warning pattern '%s' found %d time(s), instead of %d time(s) !\n",
+ log_error("Expected warning pattern '%s' found %d time(s), instead of %d time(s) !\n",
item.second.pattern.c_str(), item.second.current_count, item.second.expected_count);
}
}
@@ -700,7 +703,7 @@ void log_check_expected()
_exit(0);
#else
_Exit(0);
- #endif
+ #endif
} else {
display_error_log_msg = false;
log_warn_regexes.clear();