-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcallstack.h
More file actions
297 lines (269 loc) · 9.26 KB
/
callstack.h
File metadata and controls
297 lines (269 loc) · 9.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/*
* CallstackLibrary - Library creating human-readable call stacks.
*
* Copyright (C) 2022 - 2026 mhahnFr
*
* This file is part of the CallstackLibrary.
*
* The CallstackLibrary is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The CallstackLibrary is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with the
* CallstackLibrary, see the file LICENSE. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _lcs_callstack_h
#define _lcs_callstack_h
#include "callstack_frame.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The amount of frames to be stored in a callstack object.
*/
#define CALLSTACK_BACKTRACE_SIZE 128
/**
* The type of the callstack.
*/
enum callstack_type {
/**
* The callstack has been translated.
*
* @since v1.1
*/
TRANSLATED,
/** An error happened during translation. */
FAILED,
/** Not translated. */
NONE
};
/**
* A structure representing a callstack.
*/
struct callstack {
/** The type (status) of the translation to be human-readable. */
enum callstack_type translationStatus;
/**
* The amount of available frames.
*
* @since v1.1
*/
size_t frameCount;
/**
* An array of callstack frames.
*
* @since v1.1
*/
struct callstack_frame * frames;
/** The size of the backtrace. */
size_t backtraceSize;
/** The backtrace. */
void * backtrace[CALLSTACK_BACKTRACE_SIZE];
};
/**
* The initializing expression for the callstack object.
*
* @since v2.3
*/
#define CALLSTACK_INITIALIZER { NONE, 0, NULL, 0, {} }
/**
* @brief Creates a callstack of the calling function.
*
* The backtrace of the calling function is created.<br>
* The returned structure is allocated and needs to be freed using the function
* @code callstack_delete(struct callstack *)@endcode.<br>
* Returns @c NULL if an error occurs.
*
* @return A newly allocated callstack object.
*/
struct callstack * callstack_new(void);
/**
* @brief Creates a new callstack object, ignoring all frames after the given
* address.
*
* The returned structure is allocated and needs to be freed using the function
* @code callstack_delete(struct callstack *)@endcode.<br>
* Returns @c NULL if an error occurs.
*
* @param address The stack address after which frames are ignored.
* @return A newly allocated callstack object.
*/
struct callstack* callstack_newWithAddress(const void* address);
/**
* @brief Constructs the given callstack object.
*
* Stores the backtrace of the calling function.<br>
* The callstack object needs to be destructed using the function
* @code callstack_destroy(struct callstack *)@endcode upon successful
* construction and use.<br>
* If an error occurs during the initialization of the given callstack object,
* @c false is returned.
*
* @param self A pointer to the callstack object to be constructed.
* @return Whether the given callstack object was constructed successfully.
*/
bool callstack_emplace(struct callstack * self);
/**
* @brief Constructs the given callstack object.
*
* Stores the backtrace of the calling function, ignoring all frames after the
* given address.<br>
* The callstack object needs to be destructed using the function
* @code callstack_destroy(struct callstack *)@endcode upon successful
* construction and use.
*
* @param self A pointer to the callstack object to be constructed.
* @param address The stack address after which frames are ignored.
* @return Whether the given callstack object was constructed successfully.
*/
bool callstack_emplaceWithAddress(struct callstack* self, const void* address);
/**
* @brief Constructs the given callstack object.
*
* Copies the given callstack into the given object. If the trace is longer
* than @c CALLSTACK_BACKTRACE_SIZE, only the first addresses are copied.<br>
* The callstack object needs to be destructed using the function
* @code callstack_destroy(struct callstack *)@endcode after use.<br>
* If the given trace length is smaller than zero, @c false is returned and the
* given callstack is not modified.
*
* @param self A pointer to the callstack object to be constructed.
* @param trace The backtrace to be copied.
* @param traceLength The length of the given trace.
* @return Whether the given callstack object was constructed successfully.
*/
bool callstack_emplaceWithBacktrace(struct callstack * self,
void * trace[], int traceLength);
/**
* @brief Copies the given callstack.
*
* The given callstack is destroyed before the contents of the other one are copied.
*
* @param self A pointer to the callstack to be replaced.
* @param other The callstack object to be copied.
*/
void callstack_copy(struct callstack * self, const struct callstack * other);
/**
* @brief Relativizes the given callstack object.
*
* Upon successful return of the function, the addresses within the callstack
* object have become offsets into the runtime image they belong to. The names
* of these runtime images are stored within the given string array.
*
* @param self the callstack to be relativized
* @param binaryNames an array capable to hold the same number of strings as
* the amount of entries within the given callstack object
* @return whether the given callstack was relativized successfully
* @since v2.3
*/
bool callstack_relativize(struct callstack* self, const char** binaryNames);
/**
* @brief Translates the given relativized callstack object, using the provided array
* of binary file names.
*
* The given string array must hold at least the same amount of binary file
* names as the amount of entries within the given callstack object.
*
* @param self the relativized callstack to be translated
* @param binaryNames the names of the binary images the offsets are pointing into
* @return the translated callstack frames
* @since v2.3
*/
struct callstack_frame* callstack_translateRelative(struct callstack* self, const char** binaryNames);
/**
* @brief Translates the given callstack and returns an array of the translated frames.
*
* Returns @c NULL if an error happens.<br>
* Since version @c 1.1 a @c callstack_frame array is returned.
*
* @param self The callstack object.
* @return An array of translated callstack frames.
*/
struct callstack_frame * callstack_toArray(struct callstack * self);
/**
* @brief Translates the given callstack and returns an array of the translated frames.
*
* If the given callstack has not been translated before, only the binary file
* information is deducted.
* <br><br>
* Returns @c NULL if an error happens.
*
* @param self The callstack object.
* @return An array of translated callstack frames.
* @since v1.1
*/
struct callstack_frame * callstack_getBinaries(struct callstack * self);
#ifdef LCS_USE_UNSAFE_OPTIMIZATION
/**
* @brief Translates the given callstack and returns an array of the translated frames.
*
* If the given has not been translated before, only the binary file
* information is deducted.
*
* The deducted binary information is located in the cache of the library and
* becomes invalid after a call to @c callstack_clearCaches() or after the
* callstack has been translated entirely if @c callstack_autoClearCaches is
* @c true .
* <br><br>
* Returns @c NULL if an error happens.
*
* @param self the callstack object
* @return an array of translated callstack frames
* @since v2.0
*/
struct callstack_frame* callstack_getBinariesCached(struct callstack* self);
#endif
/**
* @brief Returns the number of frames stored in the given callstack.
*
* @param self The callstack object.
* @return The number of frames in the given callstack.
*/
static inline size_t callstack_getFrameCount(const struct callstack* self) {
return self->backtraceSize;
}
/**
* @brief Returns the type of the given callstack.
*
* @param self The callstack object.
* @return The type of the callstack.
*/
static inline enum callstack_type callstack_getType(const struct callstack* self) {
return self->translationStatus;
}
/**
* @brief Returns whether the given callstack is already translated.
*
* @param self The callstack object.
* @return Whether the callstack is already translated.
*/
static inline bool callstack_isTranslated(const struct callstack* self) {
return self->translationStatus != NONE && self->translationStatus != FAILED;
}
/**
* @brief Destroys the given callstack object.
*
* The contents of the given object are invalidated.
*
* @param self The callstack object.
*/
void callstack_destroy(struct callstack * self);
/**
* @brief Deletes the given callstack.
*
* Destroys and deallocates the given callstack object.
*
* @param self The callstack object.
*/
void callstack_delete(struct callstack * self);
#ifdef __cplusplus
} // extern "C"
#include "callstack.hpp"
#endif /* __cplusplus */
#endif /* _lcs_callstack_h */