backtrace.c revision 1.1.1.7 1 /* $NetBSD: backtrace.c,v 1.1.1.7 2025/01/26 16:12:31 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16 /*! \file */
17
18 #include <stdlib.h>
19 #include <string.h>
20 #ifdef HAVE_BACKTRACE_SYMBOLS
21 #include <execinfo.h>
22 #endif /* HAVE_BACKTRACE_SYMBOLS */
23
24 #include <isc/backtrace.h>
25 #include <isc/log.h>
26 #include <isc/result.h>
27 #include <isc/util.h>
28
29 #if HAVE_BACKTRACE_SYMBOLS
30 int
31 isc_backtrace(void **addrs, int maxaddrs) {
32 int n;
33
34 /*
35 * Validate the arguments: intentionally avoid using REQUIRE().
36 * See notes in backtrace.h.
37 */
38 if (addrs == NULL || maxaddrs <= 0) {
39 return -1;
40 }
41
42 /*
43 * backtrace(3) includes this function itself in the address array,
44 * which should be eliminated from the returned sequence.
45 */
46 n = backtrace(addrs, maxaddrs);
47 if (n < 2) {
48 return -1;
49 }
50 n--;
51 memmove(addrs, &addrs[1], sizeof(addrs[0]) * n);
52
53 return n;
54 }
55
56 char **
57 isc_backtrace_symbols(void *const *buffer, int size) {
58 return backtrace_symbols(buffer, size);
59 }
60
61 void
62 isc_backtrace_symbols_fd(void *const *buffer, int size, int fd) {
63 backtrace_symbols_fd(buffer, size, fd);
64 }
65
66 void
67 isc_backtrace_log(isc_log_t *lctx, isc_logcategory_t *category,
68 isc_logmodule_t *module, int level) {
69 void *tracebuf[ISC_BACKTRACE_MAXFRAME];
70 int nframes;
71 char **strs;
72
73 nframes = isc_backtrace(tracebuf, ISC_BACKTRACE_MAXFRAME);
74 if (nframes <= 0) {
75 return;
76 }
77 strs = isc_backtrace_symbols(tracebuf, nframes);
78 if (strs == NULL) {
79 return;
80 }
81 for (int i = 0; i < nframes; i++) {
82 isc_log_write(lctx, category, module, level, "%s", strs[i]);
83 }
84 }
85
86 #else /* HAVE_BACKTRACE_SYMBOLS */
87
88 int
89 isc_backtrace(void **addrs, int maxaddrs) {
90 UNUSED(addrs);
91 UNUSED(maxaddrs);
92
93 return -1;
94 }
95
96 char **
97 isc_backtrace_symbols(void *const *buffer, int size) {
98 UNUSED(buffer);
99 UNUSED(size);
100
101 return NULL;
102 }
103
104 void
105 isc_backtrace_symbols_fd(void *const *buffer, int size, int fd) {
106 UNUSED(buffer);
107 UNUSED(size);
108 UNUSED(fd);
109 }
110
111 void
112 isc_backtrace_log(isc_log_t *lctx, isc_logcategory_t *category,
113 isc_logmodule_t *module, int level) {
114 UNUSED(lctx);
115 UNUSED(category);
116 UNUSED(module);
117 UNUSED(level);
118 }
119
120 #endif /* HAVE_BACKTRACE_SYMBOLS */
121