Spaces:
Running
Running
Daniel Tang
commited on
Commit
·
1459465
1
Parent(s):
0cae2d6
ggml : Print backtrace on uncaught C++ exceptions (ggml/1232)
Browse filesThe 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 +1 -0
- ggml/src/ggml-impl.h +2 -0
- ggml/src/ggml.c +8 -1
- ggml/src/ggml.cpp +26 -0
ggml/src/CMakeLists.txt
CHANGED
|
@@ -194,6 +194,7 @@ add_library(ggml-base
|
|
| 194 |
../include/ggml-opt.h
|
| 195 |
../include/gguf.h
|
| 196 |
ggml.c
|
|
|
|
| 197 |
ggml-alloc.c
|
| 198 |
ggml-backend.cpp
|
| 199 |
ggml-opt.cpp
|
|
|
|
| 194 |
../include/ggml-opt.h
|
| 195 |
../include/gguf.h
|
| 196 |
ggml.c
|
| 197 |
+
ggml.cpp
|
| 198 |
ggml-alloc.c
|
| 199 |
ggml-backend.cpp
|
| 200 |
ggml-opt.cpp
|
ggml/src/ggml-impl.h
CHANGED
|
@@ -32,6 +32,8 @@
|
|
| 32 |
extern "C" {
|
| 33 |
#endif
|
| 34 |
|
|
|
|
|
|
|
| 35 |
#ifndef MIN
|
| 36 |
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
| 37 |
#endif
|
|
|
|
| 32 |
extern "C" {
|
| 33 |
#endif
|
| 34 |
|
| 35 |
+
void ggml_print_backtrace(void);
|
| 36 |
+
|
| 37 |
#ifndef MIN
|
| 38 |
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
| 39 |
#endif
|
ggml/src/ggml.c
CHANGED
|
@@ -133,7 +133,7 @@ static void ggml_print_backtrace_symbols(void) {
|
|
| 133 |
}
|
| 134 |
#endif
|
| 135 |
|
| 136 |
-
|
| 137 |
const char * GGML_NO_BACKTRACE = getenv("GGML_NO_BACKTRACE");
|
| 138 |
if (GGML_NO_BACKTRACE) {
|
| 139 |
return;
|
|
@@ -160,6 +160,10 @@ static void ggml_print_backtrace(void) {
|
|
| 160 |
const int parent_pid = getpid();
|
| 161 |
const int child_pid = fork();
|
| 162 |
if (child_pid < 0) { // error
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
return;
|
| 164 |
} else if (child_pid == 0) { // child
|
| 165 |
char attach[32];
|
|
@@ -167,6 +171,7 @@ static void ggml_print_backtrace(void) {
|
|
| 167 |
#if defined(__linux__)
|
| 168 |
close(lock[1]);
|
| 169 |
(void) !read(lock[0], lock, 1);
|
|
|
|
| 170 |
#endif
|
| 171 |
// try gdb
|
| 172 |
execlp("gdb", "gdb", "--batch",
|
|
@@ -216,6 +221,8 @@ void ggml_abort(const char * file, int line, const char * fmt, ...) {
|
|
| 216 |
abort();
|
| 217 |
}
|
| 218 |
|
|
|
|
|
|
|
| 219 |
//
|
| 220 |
// logging
|
| 221 |
//
|
|
|
|
| 133 |
}
|
| 134 |
#endif
|
| 135 |
|
| 136 |
+
void ggml_print_backtrace(void) {
|
| 137 |
const char * GGML_NO_BACKTRACE = getenv("GGML_NO_BACKTRACE");
|
| 138 |
if (GGML_NO_BACKTRACE) {
|
| 139 |
return;
|
|
|
|
| 160 |
const int parent_pid = getpid();
|
| 161 |
const int child_pid = fork();
|
| 162 |
if (child_pid < 0) { // error
|
| 163 |
+
#if defined(__linux__)
|
| 164 |
+
close(lock[1]);
|
| 165 |
+
close(lock[0]);
|
| 166 |
+
#endif
|
| 167 |
return;
|
| 168 |
} else if (child_pid == 0) { // child
|
| 169 |
char attach[32];
|
|
|
|
| 171 |
#if defined(__linux__)
|
| 172 |
close(lock[1]);
|
| 173 |
(void) !read(lock[0], lock, 1);
|
| 174 |
+
close(lock[0]);
|
| 175 |
#endif
|
| 176 |
// try gdb
|
| 177 |
execlp("gdb", "gdb", "--batch",
|
|
|
|
| 221 |
abort();
|
| 222 |
}
|
| 223 |
|
| 224 |
+
// ggml_print_backtrace is registered with std::set_terminate by ggml.cpp
|
| 225 |
+
|
| 226 |
//
|
| 227 |
// logging
|
| 228 |
//
|
ggml/src/ggml.cpp
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "ggml-impl.h"
|
| 2 |
+
|
| 3 |
+
#include <cstdlib>
|
| 4 |
+
#include <exception>
|
| 5 |
+
|
| 6 |
+
static std::terminate_handler previous_terminate_handler;
|
| 7 |
+
|
| 8 |
+
GGML_NORETURN static void ggml_uncaught_exception() {
|
| 9 |
+
ggml_print_backtrace();
|
| 10 |
+
if (previous_terminate_handler) {
|
| 11 |
+
previous_terminate_handler();
|
| 12 |
+
}
|
| 13 |
+
abort(); // unreachable unless previous_terminate_handler was nullptr
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
static bool ggml_uncaught_exception_init = []{
|
| 17 |
+
const char * GGML_NO_BACKTRACE = getenv("GGML_NO_BACKTRACE");
|
| 18 |
+
if (GGML_NO_BACKTRACE) {
|
| 19 |
+
return false;
|
| 20 |
+
}
|
| 21 |
+
const auto prev{std::get_terminate()};
|
| 22 |
+
GGML_ASSERT(prev != ggml_uncaught_exception);
|
| 23 |
+
previous_terminate_handler = prev;
|
| 24 |
+
std::set_terminate(ggml_uncaught_exception);
|
| 25 |
+
return true;
|
| 26 |
+
}();
|