9

According to this answer,it should print all function names:

[root@ test]# cat hw.c
#include <stdio.h>

int func(void)
{  
  return 1;
}
int main(void)
{
  func();
  printf("%d",6);
  return 6;
}
[root@ test]# gcc -Wall hw.c -o hw -finstrument-functions
[root@ test]# ./hw 
6
[root@ test]# gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
Copyright (C) 2006 Free Software Foundation, Inc.

But why it's not working for me?

Community
  • 1
  • 1
compile-fan
  • 16,885
  • 22
  • 59
  • 73

3 Answers3

11

This is from the gcc manual:

-finstrument-functions

Generate instrumentation calls for entry and exit to functions. Just after func- tion entry and just before function exit, the following profiling functions will be called with the address of the current function and its call site. (On some platforms, __builtin_return_address does not work beyond the current func- tion, so the call site information may not be available to the profiling functions otherwise.)

void __cyg_profile_func_enter (void *this_fn, void *call_site);

void __cyg_profile_func_exit (void *this_fn, void *call_site);

Unless somthing implements those functions, you will get linker errors (which is what happens with MinGW). Conceivably, your GCC version is providing empty implementations.

I got it to work with MinGW GCC by providing this implementation:

#include  <stdio.h>

void __cyg_profile_func_enter (void *this_fn, void *call_site) {
    printf( "entering %p\n", this_fn );
}

void __cyg_profile_func_exit (void *this_fn, void *call_site) {
    printf( "leaving %p\n", this_fn );
}

but this only gives the function addresses. I'd have thought there should be a GCC default implementation of this, but there doesn't seem to be.

People may also be interested in this visualisation of the call tree, which uses the -fintrument-functions flag - caveat, I haven't tried it myself.

AmeyaVS
  • 814
  • 10
  • 26
  • @Neil Butterworth,can I add these 2 functions into my `.c` file manually? – compile-fan May 30 '11 at 12:43
  • You could, but implementing them is pretty complicated. –  May 30 '11 at 12:44
  • @Neil Butterworth ,I just want it to print function names,why is it complicated? – compile-fan May 30 '11 at 12:47
  • Because you don't get passed the function names in those two functions. –  May 30 '11 at 12:50
  • 2
    You have to compile the code I gave separately, as C code, *without* the -finstrument-functions flag and then link the resulting .o file with your code. This works for me on MingW GCC 4.5.1, but I can't guarantee other platforms. –  May 30 '11 at 13:37
  • @Neil Butterworth ,I get `undefined reference to `main'` when compiling it separately: `gcc -Wall profile.c -o profile` – compile-fan May 30 '11 at 13:45
  • 2
    ...or instead of compiling separately, you could add `__attribute__((no_instrument_function))` to the declaration of the `__cyg_profile_func_XXX` functions, which will stop `-finstrument-functions` instrumenting the instrumentation. – Matthew Slattery May 30 '11 at 13:47
  • @Neil Butterworth ,`gcc -Wall profile.c -o profile -c` works,but when linking against it:`gcc -Wall hw.c -o hw -finstrument-functions -g -lprofile -L.`,getting `cannot find -lprofile` :( – compile-fan May 30 '11 at 13:51
  • `gcc -c profile.c -o profile.o` and then `gcc -finstrument-functions hw.c profile.o -o hw` - note profile.o is not a library. –  May 30 '11 at 13:56
  • @Neil Butterworth ,it works now! But I think `profile.o` is a static library(like .a archive file),do you think so? – compile-fan May 30 '11 at 14:14
  • No, its an object file. You can create a library with `ar rvs libprofile.a profile.o`. –  May 30 '11 at 14:19
  • @Neil Butterworth ,let's talk about this in a separate thread:) http://stackoverflow.com/questions/6177498/whats-the-difference-between-object-file-and-static-libraryarchive-file – compile-fan May 30 '11 at 14:26
  • hi, what is the difference between this option and `-pg` option? – Elinx Jan 16 '17 at 12:12
1

You didn't actually implement any instrumentation. The -finstrument-functions switch just tells gcc to call some function at entry and exit to each function. But you have to define these functions yourself (normally this is done by linking a profiler library in).

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • what additional steps do I need to take to work with `-finstrument-functions` switch? I hope that'll be as minimal as possible... – compile-fan May 30 '11 at 12:41
  • @compile-fan: The [documentation](http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-finstrument_002dfunctions-2168) mentions the two functions that have to be implemented. I don't know whether there is a ready-made library that uses them. – Jan Hudec May 30 '11 at 14:14
0

Coding __cyg_profile_func_enter and __cyg_profile_func_exit is not complicated. Easiest solution will be to ensure that the above functions write the address details to a file and have a seperate process to read the addresses from the file and resolve them using symbol table of the executable. If you try to do address resolution in the function itself it may take some time.

I came across following article - http://balau82.wordpress.com/2010/10/06/trace-and-profile-function-calls-with-gcc/

Which uses addr2line from binutils for this purpose. Check if this helps you

Samir Baid
  • 1,128
  • 2
  • 11
  • 20