Skip to content

Commit fedf034

Browse files
danielzgtgggerganov
authored andcommitted
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.
1 parent 8726392 commit fedf034

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

ggml/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ add_library(ggml-base
196196
../include/ggml-opt.h
197197
../include/gguf.h
198198
ggml.c
199+
ggml.cpp
199200
ggml-alloc.c
200201
ggml-backend.cpp
201202
ggml-opt.cpp

ggml/src/ggml-impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
extern "C" {
3333
#endif
3434

35+
void ggml_print_backtrace(void);
36+
3537
#ifndef MIN
3638
# define MIN(a, b) ((a) < (b) ? (a) : (b))
3739
#endif

ggml/src/ggml.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ static void ggml_print_backtrace_symbols(void) {
133133
}
134134
#endif
135135

136-
static void ggml_print_backtrace(void) {
136+
void ggml_print_backtrace(void) {
137137
const char * GGML_NO_BACKTRACE = getenv("GGML_NO_BACKTRACE");
138138
if (GGML_NO_BACKTRACE) {
139139
return;
@@ -160,13 +160,18 @@ static void ggml_print_backtrace(void) {
160160
const int parent_pid = getpid();
161161
const int child_pid = fork();
162162
if (child_pid < 0) { // error
163+
#if defined(__linux__)
164+
close(lock[1]);
165+
close(lock[0]);
166+
#endif
163167
return;
164168
} else if (child_pid == 0) { // child
165169
char attach[32];
166170
snprintf(attach, sizeof(attach), "attach %d", parent_pid);
167171
#if defined(__linux__)
168172
close(lock[1]);
169173
(void) !read(lock[0], lock, 1);
174+
close(lock[0]);
170175
#endif
171176
// try gdb
172177
execlp("gdb", "gdb", "--batch",
@@ -216,6 +221,8 @@ void ggml_abort(const char * file, int line, const char * fmt, ...) {
216221
abort();
217222
}
218223

224+
// ggml_print_backtrace is registered with std::set_terminate by ggml.cpp
225+
219226
//
220227
// logging
221228
//

ggml/src/ggml.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}();

0 commit comments

Comments
 (0)