mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	Implement API to set exit action to exception
This commit is contained in:
		
							parent
							
								
									c18a42cf5b
								
							
						
					
					
						commit
						1c43da6663
					
				
					 6 changed files with 66 additions and 5 deletions
				
			
		|  | @ -44,6 +44,7 @@ z3_add_component(api | ||||||
|     api_context.cpp |     api_context.cpp | ||||||
|     api_datalog.cpp |     api_datalog.cpp | ||||||
|     api_datatype.cpp |     api_datatype.cpp | ||||||
|  |     api_debug.cpp | ||||||
|     api_fpa.cpp |     api_fpa.cpp | ||||||
|     api_goal.cpp |     api_goal.cpp | ||||||
|     api_log.cpp |     api_log.cpp | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								src/api/api_debug.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/api/api_debug.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | #include "api/z3.h" | ||||||
|  | #include "util/util.h" | ||||||
|  | 
 | ||||||
|  | extern "C" { | ||||||
|  |     void Z3_API Z3_set_exit_action_to_throw_exception() { | ||||||
|  |         set_default_exit_action(exit_action::throw_exception); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -316,6 +316,11 @@ def get_param(name): | ||||||
|         return r |         return r | ||||||
|     raise Z3Exception("failed to retrieve value for '%s'" % name) |     raise Z3Exception("failed to retrieve value for '%s'" % name) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | def set_exit_action_to_throw_exception(): | ||||||
|  |     """Set the debug exit action to throw exception""" | ||||||
|  |     Z3_set_exit_action_to_throw_exception() | ||||||
|  | 
 | ||||||
| ######################################### | ######################################### | ||||||
| # | # | ||||||
| # ASTs base class | # ASTs base class | ||||||
|  |  | ||||||
|  | @ -7455,6 +7455,13 @@ extern "C" { | ||||||
| 
 | 
 | ||||||
|     /**@}*/ |     /**@}*/ | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |     \brief Set exit action to throw exception. | ||||||
|  | 
 | ||||||
|  |     def_API('Z3_set_exit_action_to_throw_exception', VOID, ()) | ||||||
|  |     */ | ||||||
|  |     void Z3_API Z3_set_exit_action_to_throw_exception(); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif // __cplusplus
 | #endif // __cplusplus
 | ||||||
|  |  | ||||||
|  | @ -75,6 +75,37 @@ bool is_debug_enabled(const char * tag) { | ||||||
|     return g_enabled_debug_tags->contains(tag); |     return g_enabled_debug_tags->contains(tag); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | atomic<exit_action> g_default_exit_action(exit_action::exit); | ||||||
|  | 
 | ||||||
|  | exit_action get_default_exit_action() { | ||||||
|  |     return g_default_exit_action; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void set_default_exit_action(exit_action a) { | ||||||
|  |     g_default_exit_action = a; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void invoke_exit_action(unsigned int code) { | ||||||
|  |     exit_action a = get_default_exit_action(); | ||||||
|  |     switch (a) { | ||||||
|  |     case exit_action::exit: | ||||||
|  |         exit(code); | ||||||
|  |     case exit_action::throw_exception: | ||||||
|  |         switch (code) { | ||||||
|  |             case ERR_INTERNAL_FATAL: | ||||||
|  |                 throw default_exception("internal fatal"); | ||||||
|  |             case ERR_UNREACHABLE: | ||||||
|  |                 throw default_exception("unreachable"); | ||||||
|  |             case ERR_NOT_IMPLEMENTED_YET: | ||||||
|  |                 throw default_exception("not implemented yet"); | ||||||
|  |             default: | ||||||
|  |                 throw default_exception("unknown"); | ||||||
|  |         } | ||||||
|  |     default: | ||||||
|  |         exit(code); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| atomic<debug_action> g_default_debug_action(debug_action::ask); | atomic<debug_action> g_default_debug_action(debug_action::ask); | ||||||
| 
 | 
 | ||||||
| debug_action get_default_debug_action() { | debug_action get_default_debug_action() { | ||||||
|  |  | ||||||
|  | @ -35,6 +35,14 @@ enum class debug_action { | ||||||
| debug_action get_default_debug_action(); | debug_action get_default_debug_action(); | ||||||
| void set_default_debug_action(debug_action a); | void set_default_debug_action(debug_action a); | ||||||
| 
 | 
 | ||||||
|  | enum class exit_action { | ||||||
|  |     exit, | ||||||
|  |     throw_exception, | ||||||
|  | }; | ||||||
|  | exit_action get_default_exit_action(); | ||||||
|  | void set_default_exit_action(exit_action a); | ||||||
|  | void invoke_exit_action(unsigned int code); | ||||||
|  | 
 | ||||||
| #include "util/error_codes.h" | #include "util/error_codes.h" | ||||||
| #include "util/warning.h" | #include "util/warning.h" | ||||||
| 
 | 
 | ||||||
|  | @ -56,7 +64,7 @@ void set_default_debug_action(debug_action a); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef NO_Z3_DEBUGGER | #ifdef NO_Z3_DEBUGGER | ||||||
| #define INVOKE_DEBUGGER() exit(ERR_INTERNAL_FATAL) | #define INVOKE_DEBUGGER() invoke_exit_action(ERR_INTERNAL_FATAL) | ||||||
| #else | #else | ||||||
| #ifdef _WINDOWS | #ifdef _WINDOWS | ||||||
| #define INVOKE_DEBUGGER() __debugbreak() | #define INVOKE_DEBUGGER() __debugbreak() | ||||||
|  | @ -71,6 +79,7 @@ void enable_debug(const char * tag); | ||||||
| void disable_debug(const char * tag); | void disable_debug(const char * tag); | ||||||
| bool is_debug_enabled(const char * tag); | bool is_debug_enabled(const char * tag); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #define SASSERT(COND) DEBUG_CODE(if (assertions_enabled() && !(COND)) { notify_assertion_violation(__FILE__, __LINE__, #COND); INVOKE_DEBUGGER(); }) | #define SASSERT(COND) DEBUG_CODE(if (assertions_enabled() && !(COND)) { notify_assertion_violation(__FILE__, __LINE__, #COND); INVOKE_DEBUGGER(); }) | ||||||
| #define CASSERT(TAG, COND) DEBUG_CODE(if (assertions_enabled() && is_debug_enabled(TAG) && !(COND)) { notify_assertion_violation(__FILE__, __LINE__, #COND); INVOKE_DEBUGGER(); }) | #define CASSERT(TAG, COND) DEBUG_CODE(if (assertions_enabled() && is_debug_enabled(TAG) && !(COND)) { notify_assertion_violation(__FILE__, __LINE__, #COND); INVOKE_DEBUGGER(); }) | ||||||
| #define XASSERT(COND, EXTRA_CODE) DEBUG_CODE(if (assertions_enabled() && !(COND)) { notify_assertion_violation(__FILE__, __LINE__, #COND); { EXTRA_CODE } INVOKE_DEBUGGER(); }) | #define XASSERT(COND, EXTRA_CODE) DEBUG_CODE(if (assertions_enabled() && !(COND)) { notify_assertion_violation(__FILE__, __LINE__, #COND); { EXTRA_CODE } INVOKE_DEBUGGER(); }) | ||||||
|  | @ -85,25 +94,25 @@ bool is_debug_enabled(const char * tag); | ||||||
| #ifdef Z3DEBUG | #ifdef Z3DEBUG | ||||||
| # define UNREACHABLE() DEBUG_CODE(notify_assertion_violation(__FILE__, __LINE__, "UNEXPECTED CODE WAS REACHED."); INVOKE_DEBUGGER();) | # define UNREACHABLE() DEBUG_CODE(notify_assertion_violation(__FILE__, __LINE__, "UNEXPECTED CODE WAS REACHED."); INVOKE_DEBUGGER();) | ||||||
| #else | #else | ||||||
| # define UNREACHABLE() { notify_assertion_violation(__FILE__, __LINE__, "UNEXPECTED CODE WAS REACHED."); exit(ERR_UNREACHABLE); } ((void) 0) | # define UNREACHABLE() { notify_assertion_violation(__FILE__, __LINE__, "UNEXPECTED CODE WAS REACHED."); invoke_exit_action(ERR_UNREACHABLE); } ((void) 0) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef Z3DEBUG | #ifdef Z3DEBUG | ||||||
| # define NOT_IMPLEMENTED_YET() DEBUG_CODE(notify_assertion_violation(__FILE__, __LINE__, "NOT IMPLEMENTED YET!"); INVOKE_DEBUGGER();) | # define NOT_IMPLEMENTED_YET() DEBUG_CODE(notify_assertion_violation(__FILE__, __LINE__, "NOT IMPLEMENTED YET!"); INVOKE_DEBUGGER();) | ||||||
| #else | #else | ||||||
| # define NOT_IMPLEMENTED_YET() { notify_assertion_violation(__FILE__, __LINE__, "NOT IMPLEMENTED YET!"); exit(ERR_NOT_IMPLEMENTED_YET); } ((void) 0) | # define NOT_IMPLEMENTED_YET() { notify_assertion_violation(__FILE__, __LINE__, "NOT IMPLEMENTED YET!"); invoke_exit_action(ERR_NOT_IMPLEMENTED_YET); } ((void) 0) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define VERIFY(_x_) if (!(_x_)) {                                                       \ | #define VERIFY(_x_) if (!(_x_)) {                                                       \ | ||||||
|         notify_assertion_violation(__FILE__, __LINE__, "Failed to verify: " #_x_ "\n"); \ |         notify_assertion_violation(__FILE__, __LINE__, "Failed to verify: " #_x_ "\n"); \ | ||||||
|         exit(ERR_UNREACHABLE);                                                          \ |         invoke_exit_action(ERR_UNREACHABLE);                                                          \ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| #define VERIFY_EQ(LHS, RHS)                                                                         \ | #define VERIFY_EQ(LHS, RHS)                                                                         \ | ||||||
|     if (!((LHS) == (RHS))) {                                                                        \ |     if (!((LHS) == (RHS))) {                                                                        \ | ||||||
|         notify_assertion_violation(__FILE__, __LINE__, "Failed to verify: " #LHS " == " #RHS "\n"); \ |         notify_assertion_violation(__FILE__, __LINE__, "Failed to verify: " #LHS " == " #RHS "\n"); \ | ||||||
|         std::cerr << "LHS value: " << (LHS) << "\nRHS value: " << (RHS) << "\n";                    \ |         std::cerr << "LHS value: " << (LHS) << "\nRHS value: " << (RHS) << "\n";                    \ | ||||||
|         exit(ERR_UNREACHABLE);                                                                      \ |         invoke_exit_action(ERR_UNREACHABLE);                                                                      \ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| #define ENSURE(_x_) VERIFY(_x_) | #define ENSURE(_x_) VERIFY(_x_) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue