tags:

views:

279

answers:

4

Hi,

I am going to implement an internal profiler for memory on linux. I want to save the stack for each malloc/free/realloc. I am trying to use "pstack" to get the stack trace everytime. But the overhead is too high. Is there any lightweigt approach to get the call stack in C code?

I know there are some tools like "valgrind, google profiler", but don't know how they remebmer the stacks for each action.

Any comment is appreciated.

Thanks.

+3  A: 

There is a GNU function backtrace() which is relatively fast - it just returns array of addresses.

To resolve these addresses to function names you need to use backtrace_symbols() which is much heavier but hopefully you don't need to run it too often.

To get backtrace_symbols() actually resolve names you need to use -rdynamic linker options.

See man backtrace for details.

qrdl
+2  A: 

You can make your own function to get the caller:

static inline void *get_caller(void) {
    unsigned long *ebp;

    /* WARNING: This is working only with frame pointers */
    asm ("movl %%ebp, %0" : "=r" (ebp) : );
    ebp = (unsigned long*)*ebp;
    ebp = (unsigned long*)*(ebp+1);
    return ebp;
}

void *malloc(void) {
    void *caller = get_caller();
    ...    
}

"ebp = (unsigned long*)*ebp;" will make you go through the stack (if you need more of that stack trace).

Nicolas Viennot
thanks a lot. This is what I like.
limi
A: 

Watch out for recursions with backtrace_symbols(), which calls malloc itself.

Also note that at the first use of backtrace() and friends the dynamic linker will try to load libgcc, which will yet again invoke malloc.

Gilad

gby
A: 

Hi

Now I meet a problem on 64bit.

On 64bit, RBP is not strictly maintained. For example, gcc -O3 will use RBP as a normal caller saved register. So in this case, to get call stacks from frame pointers doesn't work.:(

Any comments?

limi
on 64bit, now I am using backtrace()
limi