]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
ggml : Print backtrace on uncaught C++ exceptions (ggml/1232)
authorDaniel Tang <redacted>
Wed, 28 May 2025 00:58:46 +0000 (20:58 -0400)
committerGeorgi Gerganov <redacted>
Sun, 1 Jun 2025 10:43:57 +0000 (13:43 +0300)
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.

ggml/src/CMakeLists.txt
ggml/src/ggml-impl.h
ggml/src/ggml.c
ggml/src/ggml.cpp [new file with mode: 0644]

index 5681ecddba782a76128ac10997b73d80af5d81f8..ac7b6946e3dae47952026014a7aa0a4f64ecaac9 100644 (file)
@@ -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
index 89b59d9aadc7e5dc3d223d5405ad7dd05866fd25..6dc5ce0d92fd86b00626728e895fc64ff7ac8c58 100644 (file)
@@ -32,6 +32,8 @@
 extern "C" {
 #endif
 
+void ggml_print_backtrace(void);
+
 #ifndef MIN
 #    define MIN(a, b) ((a) < (b) ? (a) : (b))
 #endif
index fb0d379dc8d68284c168e0c091395caad686fce9..8c941cdf8a804a30d07037871537a5fc3ff736d5 100644 (file)
@@ -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
 //
diff --git a/ggml/src/ggml.cpp b/ggml/src/ggml.cpp
new file mode 100644 (file)
index 0000000..0d388d4
--- /dev/null
@@ -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;
+}();