I am working with the following scenario: I need to get the call stack at the entry point of some APIs. So I wrote some wrappers and use libunwind
to perform stack backtracing before executing the real API.
For example:
#include <libunwind.h>
void doBackTrace() {
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
while (unw_step(&cursor) > 0) {
unw_word_t offset, pc;
char fname[FUNC_NAME_LENGTH];
unw_get_reg(&cursor, UNW_REG_IP, &pc);
unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
}
}
void funcE() {
doBackTrace();
}
void funcC() {
funcE();
}
void funcD() {
funcE();
}
void funcB() {
funcC();
funcD();
}
void funcA() {
funcB();
funcC();
funcD();
funcE();
}
int main() {
funcA()
return 0;
}
In the above code, funcE()
is responsible for stack backtracing using libunwind
, which would be executed for four times. Some times call path share the same prefix, such as A -> B -> C -> E and A -> B -> D -> E in the example. The question is, due to the fact that the call stack is organized in a single-direction linked list, I could not judge whether the prefix has already appeared in the previous backtracing until I traverse the whole path to the root using unw_step
, which has an overhead of O(N)
, where N is the depth of the call stack. So how to reduce the backtracing overhead for calls sharing the same prefix?