I wrote call logging example just for fun. A macro change the function call with an instrumented one.
include <stdio.h>. 
int funcA( int a, int b ){ return a+b; }
// instrumentation
void call_log(const char*file,const char*function,const int line,const char*args){
  printf("file:%s line: %i function: %s args: %s\n",file,line,function,args);
}
#define funcA(...) \ 
  (call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__), funcA(__VA_ARGS__)). 
// testing
void funcB(void){
  funcA(7,8);
}
int main(void){
  int x = funcA(1,2)+
          funcA(3,4);
  printf( "x: %i (==10)\n", x );
  funcA(5,6);
  funcB();
}
Output:
file:main.c line: 22 function: main args: 1,2
file:main.c line: 24 function: main args: 3,4
x: 10 (==10)
file:main.c line: 28 function: main args: 5,6
file:main.c line: 17 function: funcB args: 7,8