Skip to content

Commit 059612b

Browse files
committed
Added possibility to provide stack addresses
1 parent c21c087 commit 059612b

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

code/callstack.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@
2424
#include <string.h>
2525

2626
struct callstack * callstack_new() {
27+
return callstack_newWithAddress(__builtin_return_address(0));
28+
}
29+
30+
struct callstack * callstack_newWithAddress(void * address) {
2731
void * trace[CALLSTACK_BACKTRACE_SIZE];
28-
int size = backtrace(trace, CALLSTACK_BACKTRACE_SIZE);
32+
int size = callstack_backtrace(trace, CALLSTACK_BACKTRACE_SIZE, address);
2933
if (size < 0) return NULL;
3034

3135
struct callstack * ret = callstack_allocate();
@@ -36,8 +40,12 @@ struct callstack * callstack_new() {
3640
}
3741

3842
bool callstack_emplace(struct callstack * self) {
43+
return callstack_emplaceWithAddress(self, __builtin_return_address(0));
44+
}
45+
46+
bool callstack_emplaceWithAddress(struct callstack * self, void * address) {
3947
void * trace[CALLSTACK_BACKTRACE_SIZE];
40-
int size = backtrace(trace, CALLSTACK_BACKTRACE_SIZE);
48+
int size = callstack_backtrace(trace, CALLSTACK_BACKTRACE_SIZE, address);
4149
return callstack_emplaceWithBacktrace(self, trace, size);
4250
}
4351

code/callstackInternal.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "callstack_parser.h"
2222
#include "../include/callstack_defs.h"
2323

24+
#include <execinfo.h>
2425
#include <string.h>
2526

2627
void callstack_createWithBacktrace(struct callstack * self,
@@ -31,6 +32,17 @@ void callstack_createWithBacktrace(struct callstack * self,
3132
self->backtraceSize = traceLength;
3233
}
3334

35+
int callstack_backtrace(void * buffer[], int bufferSize, void * address) {
36+
int i,
37+
frames = backtrace(buffer, bufferSize);
38+
39+
if (frames < 0) return frames;
40+
41+
for (i = 0; buffer[i] != address && i < bufferSize; ++i);
42+
(void) memmove(buffer, buffer + i, (size_t) bufferSize - i);
43+
return frames - i;
44+
}
45+
3446
enum callstack_type callstack_translate(struct callstack * self) {
3547
struct callstack_parser parser;
3648
callstack_parser_create(&parser);

code/callstackInternal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ void callstack_createWithBacktrace(struct callstack * self,
5555
*/
5656
size_t callstack_getTotalStringLength(struct callstack * self);
5757

58+
int callstack_backtrace(void * buffer[], int bufferSize, void * address);
59+
5860
/**
5961
* @brief Translates the given callstack object into a human readable format.
6062
*

include/callstack.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,43 @@ struct callstack {
5454
*/
5555
struct callstack * callstack_new(void);
5656

57+
/**
58+
* @brief Creates a new callstack object, ignoring all frames after the given address.
59+
*
60+
* The struct is allocated and needs to be freed using the function callstack_delete(struct callstack *).
61+
* Returns NULL if an error occurs.
62+
*
63+
* @param address The stack address after which frames are ignored.
64+
* @return A newly allocated callstack object.
65+
*/
66+
struct callstack * callstack_newWithAddress(void * address);
67+
5768
/**
5869
* @brief Constructs the given callstack object.
5970
*
6071
* Stores the backtrace of the calling function.
6172
* The callstack object needs to be destructed using the function callstack_destroy(struct callstack *)
62-
* after use.
73+
* upon successfull construction and use.
6374
* If an error occurs during the initialization of the given callstack object, false is returned.
6475
*
6576
* @param self A pointer to the callstack object to be constructed.
6677
* @return Whether the given callstack object was constructed successfully.
6778
*/
6879
bool callstack_emplace(struct callstack * self);
6980

81+
/**
82+
* @brief Constructs the given callstack object.
83+
*
84+
* Stores the backtrace of the calling function, ignoring all frames after the given address.
85+
* The callstack object needs to be destructed using the function callstack_destroy(struct callstack *)
86+
* upon successfull construction and use.
87+
*
88+
* @param self A pointer to the callstack object to be constructed.
89+
* @param address The stack address after which frames are ignored.
90+
* @return Whether the given callstack object was constructed successfully.
91+
*/
92+
bool callstack_emplaceWithAddress(struct callstack * self, void * address);
93+
7094
/**
7195
* @brief Constructs the given callstack object.
7296
*

0 commit comments

Comments
 (0)