Merge pull request #2000 from whitequark/log_error-trap

kernel: Trap in `log_error()` when a debugger is attached
This commit is contained in:
whitequark 2020-05-03 16:19:42 +00:00 committed by GitHub
commit d1c8837572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 3 deletions

View File

@ -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;

View File

@ -50,9 +50,12 @@
std::regex_constants::egrep)
#endif
#ifndef _WIN32
#if defined(_WIN32)
# include <intrin.h>
#else
# include <sys/time.h>
# include <sys/resource.h>
# include <signal.h>
#endif
#if defined(_MSC_VER)
@ -69,6 +72,41 @@ YOSYS_NAMESPACE_BEGIN
#define S__LINE__sub1(x) S__LINE__sub2(x)
#define S__LINE__ S__LINE__sub1(__LINE__)
// YS_DEBUGTRAP is a macro that is functionally equivalent to a breakpoint
// if the platform provides such functionality, and does nothing otherwise.
// If no debugger is attached, it starts a just-in-time debugger if available,
// and crashes the process otherwise.
#if defined(_WIN32)
# define YS_DEBUGTRAP __debugbreak()
#else
# ifndef __has_builtin
// __has_builtin is a GCC/Clang extension; on a different compiler (or old enough GCC/Clang)
// that does not have it, using __has_builtin(...) is a syntax error.
# define __has_builtin(x) 0
# endif
# if __has_builtin(__builtin_debugtrap)
# define YS_DEBUGTRAP __builtin_debugtrap()
# elif defined(__unix__)
# define YS_DEBUGTRAP raise(SIGTRAP)
# else
# define YS_DEBUGTRAP do {} while(0)
# endif
#endif
// YS_DEBUGTRAP_IF_DEBUGGING is a macro that is functionally equivalent to a breakpoint
// if a debugger is attached, and does nothing otherwise.
#if defined(_WIN32)
# define YS_DEBUGTRAP_IF_DEBUGGING do { if (IsDebuggerPresent()) DebugBreak(); } while(0)
#elif defined(__unix__)
// There is no reliable (or portable) *nix equivalent of IsDebuggerPresent(). However,
// debuggers will stop when SIGTRAP is raised, even if the action is set to ignore.
# define YS_DEBUGTRAP_IF_DEBUGGING do { \
sighandler_t old = signal(SIGTRAP, SIG_IGN); raise(SIGTRAP); signal(SIGTRAP, old); \
} while(0)
#else
# define YS_DEBUGTRAP_IF_DEBUGGING do {} while(0)
#endif
struct log_cmd_error_exception { };
extern std::vector<FILE*> log_files;