How to reduce the overhead of libunwind

179 views Asked by At

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?

0

There are 0 answers