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