master
c 65 lines 1.8 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "stacktrace-common.h"
4
5 // This implementation is used when no stacktrace backend is available
6 #if defined(USE_NOTRACE)
7
8 const char *stacktrace_backend(void) {
9 return "none";
10 }
11
12 bool stacktrace_available(void) {
13 return false;
14 }
15
16 void impl_stacktrace_init(void) {
17 // Nothing to initialize for null backend
18 }
19
20 void stacktrace_flush(void) {
21 // Nothing to flush
22 }
23
24 bool stacktrace_capture_is_async_signal_safe(void) {
25 return false;
26 }
27
28 NEVER_INLINE
29 void stacktrace_capture(BUFFER *wb) {
30 root_cause_function[0] = '\0';
31
32 buffer_strcat(wb, NO_STACK_TRACE_PREFIX "no back-end available");
33
34 // probably we can have something like this?
35 // https://maskray.me/blog/2022-04-09-unwinding-through-signal-handler
36 // (at the end - but it needs the frame pointer)
37 }
38
39 // Simple dummy implementation for platforms without stack trace support
40 int impl_stacktrace_get_frames(void **frames, int max_frames, int skip_frames) {
41 if (!frames || max_frames <= 0)
42 return 0;
43
44 // No need to adjust skip_frames here as we're just creating a dummy frame
45 // but we include the comment for consistency with other implementations
46 // skip_frames += 1; // Skip this function itself
47
48 // Just use a counter to create a unique "frame"
49 static uint64_t counter = 0;
50 uint64_t id = __atomic_fetch_add(&counter, 1, __ATOMIC_SEQ_CST);
51
52 // Store one dummy frame
53 frames[0] = (void *)(uintptr_t)id;
54
55 return 1;
56 }
57
58 void impl_stacktrace_to_buffer(STACKTRACE trace, BUFFER *wb) {
59 struct stacktrace *st = (struct stacktrace *)trace;
60
61 // Simple representation for platforms without stack trace support
62 buffer_sprintf(wb, NO_STACK_TRACE_PREFIX "no back-end available (id: %" PRIu64 ")", st->hash);
63 }
64
65 #endif // USE_NOTRACE