mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-29 18:52:30 +00:00 
			
		
		
		
	Merge pull request #2000 from whitequark/log_error-trap
kernel: Trap in `log_error()` when a debugger is attached
This commit is contained in:
		
						commit
						d1c8837572
					
				
					 2 changed files with 44 additions and 3 deletions
				
			
		|  | @ -354,6 +354,9 @@ static void logv_error_with_prefix(const char *prefix, | ||||||
| 
 | 
 | ||||||
| 	if (check_expected_logs) | 	if (check_expected_logs) | ||||||
| 		log_check_expected(); | 		log_check_expected(); | ||||||
|  | 
 | ||||||
|  | 	YS_DEBUGTRAP_IF_DEBUGGING; | ||||||
|  | 
 | ||||||
| #ifdef EMSCRIPTEN | #ifdef EMSCRIPTEN | ||||||
| 	log_files = backup_log_files; | 	log_files = backup_log_files; | ||||||
| 	throw 0; | 	throw 0; | ||||||
|  | @ -673,7 +676,7 @@ void log_check_expected() | ||||||
| 		} | 		} | ||||||
| 		if (item.second.current_count != item.second.expected_count) { | 		if (item.second.current_count != item.second.expected_count) { | ||||||
| 			log_warn_regexes.clear(); | 			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); | 				item.second.pattern.c_str(), item.second.current_count, item.second.expected_count); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -700,7 +703,7 @@ void log_check_expected() | ||||||
| 				_exit(0); | 				_exit(0); | ||||||
| 			#else | 			#else | ||||||
| 				_Exit(0); | 				_Exit(0); | ||||||
| 			#endif			 | 			#endif | ||||||
| 		} else { | 		} else { | ||||||
| 			display_error_log_msg = false; | 			display_error_log_msg = false; | ||||||
| 			log_warn_regexes.clear(); | 			log_warn_regexes.clear(); | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								kernel/log.h
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								kernel/log.h
									
										
									
									
									
								
							|  | @ -50,9 +50,12 @@ | ||||||
| 					std::regex_constants::egrep) | 					std::regex_constants::egrep) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef _WIN32 | #if defined(_WIN32) | ||||||
|  | #  include <intrin.h> | ||||||
|  | #else | ||||||
| #  include <sys/time.h> | #  include <sys/time.h> | ||||||
| #  include <sys/resource.h> | #  include <sys/resource.h> | ||||||
|  | #  include <signal.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(_MSC_VER) | #if defined(_MSC_VER) | ||||||
|  | @ -69,6 +72,41 @@ YOSYS_NAMESPACE_BEGIN | ||||||
| #define S__LINE__sub1(x) S__LINE__sub2(x) | #define S__LINE__sub1(x) S__LINE__sub2(x) | ||||||
| #define S__LINE__ S__LINE__sub1(__LINE__) | #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 { }; | struct log_cmd_error_exception { }; | ||||||
| 
 | 
 | ||||||
| extern std::vector<FILE*> log_files; | extern std::vector<FILE*> log_files; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue