mirror of
				https://github.com/ggml-org/llama.cpp.git
				synced 2025-10-30 08:42:00 +00:00 
			
		
		
		
	ggml : Print backtrace on uncaught C++ exceptions (ggml/1232)
The goal is to have what users call "full logs" contain the backtrace. This is registered upon ggml_init. Also fixes a minor fd leak on Linux.
This commit is contained in:
		 Daniel Tang
					Daniel Tang
				
			
				
					committed by
					
						 Georgi Gerganov
						Georgi Gerganov
					
				
			
			
				
	
			
			
			 Georgi Gerganov
						Georgi Gerganov
					
				
			
						parent
						
							8726392d3d
						
					
				
				
					commit
					fedf034a98
				
			| @@ -196,6 +196,7 @@ add_library(ggml-base | ||||
|             ../include/ggml-opt.h | ||||
|             ../include/gguf.h | ||||
|             ggml.c | ||||
|             ggml.cpp | ||||
|             ggml-alloc.c | ||||
|             ggml-backend.cpp | ||||
|             ggml-opt.cpp | ||||
|   | ||||
| @@ -32,6 +32,8 @@ | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| void ggml_print_backtrace(void); | ||||
|  | ||||
| #ifndef MIN | ||||
| #    define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||||
| #endif | ||||
|   | ||||
| @@ -133,7 +133,7 @@ static void ggml_print_backtrace_symbols(void) { | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void ggml_print_backtrace(void) { | ||||
| void ggml_print_backtrace(void) { | ||||
|     const char * GGML_NO_BACKTRACE = getenv("GGML_NO_BACKTRACE"); | ||||
|     if (GGML_NO_BACKTRACE) { | ||||
|         return; | ||||
| @@ -160,6 +160,10 @@ static void ggml_print_backtrace(void) { | ||||
|     const int parent_pid = getpid(); | ||||
|     const int child_pid = fork(); | ||||
|     if (child_pid < 0) { // error | ||||
| #if defined(__linux__) | ||||
|         close(lock[1]); | ||||
|         close(lock[0]); | ||||
| #endif | ||||
|         return; | ||||
|     } else if (child_pid == 0) { // child | ||||
|         char attach[32]; | ||||
| @@ -167,6 +171,7 @@ static void ggml_print_backtrace(void) { | ||||
| #if defined(__linux__) | ||||
|         close(lock[1]); | ||||
|         (void) !read(lock[0], lock, 1); | ||||
|         close(lock[0]); | ||||
| #endif | ||||
|         // try gdb | ||||
|         execlp("gdb", "gdb", "--batch", | ||||
| @@ -216,6 +221,8 @@ void ggml_abort(const char * file, int line, const char * fmt, ...) { | ||||
|     abort(); | ||||
| } | ||||
|  | ||||
| // ggml_print_backtrace is registered with std::set_terminate by ggml.cpp | ||||
|  | ||||
| // | ||||
| // logging | ||||
| // | ||||
|   | ||||
							
								
								
									
										26
									
								
								ggml/src/ggml.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								ggml/src/ggml.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| #include "ggml-impl.h" | ||||
|  | ||||
| #include <cstdlib> | ||||
| #include <exception> | ||||
|  | ||||
| static std::terminate_handler previous_terminate_handler; | ||||
|  | ||||
| GGML_NORETURN static void ggml_uncaught_exception() { | ||||
|     ggml_print_backtrace(); | ||||
|     if (previous_terminate_handler) { | ||||
|         previous_terminate_handler(); | ||||
|     } | ||||
|     abort(); // unreachable unless previous_terminate_handler was nullptr | ||||
| } | ||||
|  | ||||
| static bool ggml_uncaught_exception_init = []{ | ||||
|     const char * GGML_NO_BACKTRACE = getenv("GGML_NO_BACKTRACE"); | ||||
|     if (GGML_NO_BACKTRACE) { | ||||
|         return false; | ||||
|     } | ||||
|     const auto prev{std::get_terminate()}; | ||||
|     GGML_ASSERT(prev != ggml_uncaught_exception); | ||||
|     previous_terminate_handler = prev; | ||||
|     std::set_terminate(ggml_uncaught_exception); | ||||
|     return true; | ||||
| }(); | ||||
		Reference in New Issue
	
	Block a user