forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			74 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| #ifndef SUPPORT_ASSERT_CHECKPOINT_H
 | |
| #define SUPPORT_ASSERT_CHECKPOINT_H
 | |
| 
 | |
| #include <csignal>
 | |
| #include <iostream>
 | |
| #include <cstdlib>
 | |
| 
 | |
| struct Checkpoint {
 | |
|   const char* file;
 | |
|   const char* func;
 | |
|   int line;
 | |
|   const char* msg;
 | |
| 
 | |
|   Checkpoint() : file(nullptr), func(nullptr), line(-1), msg(nullptr) {}
 | |
|   Checkpoint(const char* xfile, const char* xfunc, int xline, const char* xmsg)
 | |
|       : file(xfile), func(xfunc), line(xline), msg(xmsg)
 | |
|   {}
 | |
| 
 | |
|   template <class Stream>
 | |
|   void print(Stream& s) const {
 | |
|       if (!file) {
 | |
|           s << "NO CHECKPOINT\n";
 | |
|           return;
 | |
|       }
 | |
|       s << file << ":" << line << " " << func << ": Checkpoint";
 | |
|       if (msg)
 | |
|         s << " '" << msg << "'";
 | |
|       s << std::endl;
 | |
|   }
 | |
| };
 | |
| 
 | |
| inline Checkpoint& globalCheckpoint() {
 | |
|     static Checkpoint C;
 | |
|     return C;
 | |
| }
 | |
| 
 | |
| inline void clearCheckpoint() {
 | |
|     globalCheckpoint() = Checkpoint();
 | |
| }
 | |
| 
 | |
| #if defined(__GNUC__)
 | |
| #define CHECKPOINT_FUNCTION_NAME __PRETTY_FUNCTION__
 | |
| #else
 | |
| #define CHECKPOINT_FUNCTION_NAME __func__
 | |
| #endif
 | |
| 
 | |
| #define CHECKPOINT(msg) globalCheckpoint() = Checkpoint(__FILE__, CHECKPOINT_FUNCTION_NAME, __LINE__, msg);
 | |
| 
 | |
| inline void checkpointSignalHandler(int signal) {
 | |
|     if (signal == SIGABRT) {
 | |
|         globalCheckpoint().print(std::cerr);
 | |
|     } else {
 | |
|         std::cerr << "Unexpected signal " << signal << " received\n";
 | |
|     }
 | |
|     std::_Exit(EXIT_FAILURE);
 | |
| }
 | |
| 
 | |
| inline bool initCheckpointHandler() {
 | |
|     typedef void(*HandlerT)(int);
 | |
|     static bool isInit = false;
 | |
|     if (isInit) return true;
 | |
|     HandlerT prev_h = std::signal(SIGABRT, checkpointSignalHandler);
 | |
|     if (prev_h == SIG_ERR) {
 | |
|         std::cerr << "Setup failed.\n";
 | |
|         std::_Exit(EXIT_FAILURE);
 | |
|     }
 | |
|     isInit = true;
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| static bool initDummy = initCheckpointHandler();
 | |
| 
 | |
| #endif
 |