You can instruct the compiler to insert calls to user-defined tracing functions to aid in debugging or timing the execution of other functions.
The following C example shows how you can trace functions in your code using function prototypes. Assume you want to trace the entry and exit points of function1 and function2, as well as how much time it takes the compiler to trace them in the following code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#ifdef __cplusplus
extern "C"
#endif
void __func_trace_enter(const char *function_name, const char *file_name,
int line_number, void** const user_data){
if((*user_data)==NULL)
(*user_data)=(time_t *)malloc(sizeof(time_t));
(*(time_t *)*user_data)=time(NULL);
printf("begin function: name=%s file=%s line=%d\n",function_name,file_name,
line_number);
}
#ifdef __cplusplus
extern "C"
#endif
void __func_trace_exit(const char *function_name, const char*file_name,
int line_number, void** const user_data){
printf("end function: name=%s file=%s line=%d. It took %g seconds\n",
function_name,file_name,line_number, difftime(time(NULL),
*(time_t *)*user_data));
}
void function2(void){
sleep(3);
}
void function1(void){
sleep(5);
function2();
}
int main(){
function1();
}
xlc t1.c -qfunctrace+function1:function2
begin function: name=function1 file=t.c line=27
begin function: name=function2 file=t.c line=24
end function: name=function2 file=t.c line=25. It took 3 seconds
end function: name=function1 file=t.c line=29. It took 8 seconds
The following C++ example shows how tracing functions are called. The following example traces class myStack, function foo, and disables tracing for int main() using #pragma nofunctrace:
#include <iostream>
#include <vector>
#include <stdexcept>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
extern "C"
void __func_trace_enter(const char *function_name, const char *file_name,
int line_number, void** const user_data){
if((*user_data)==NULL)
(*user_data)=(time_t *)malloc(sizeof(time_t));
(*(time_t *)*user_data)=time(NULL);
printf("enter function: name=%s file=%s line=%d\n",function_name,file_name,
line_number);
}
extern "C"
void __func_trace_exit(const char *function_name, const char*file_name,
int line_number, void** const user_data){
printf("exit function: name=%s file=%s line=%d. It took %g seconds\n",
function_name, file_name, line_number, difftime(time(NULL),
*(time_t *)*user_data));
}
extern "C"
void __func_trace_catch(const char *function_name, const char*file_name,
int line_number, void** const user_data){
printf("catch function: name=%s file=%s line=%d. It took %g seconds\n",
function_name, file_name,line_number, difftime(time(NULL),
*(time_t *)*user_data));
}
template <typename T> class myStack{
private:
std::vector<T> elements;
public:
void push(T const&);
void pop();
};
template <typename T>
void myStack<T>::push(T const& value){
sleep(3);
std::cout<< "\tpush(" << value << ")" <<std::endl;
elements.push_back(value);
}
template <typename T>
void myStack<T>::pop(){
sleep(5);
std::cout<< "\tpop()" <<std::endl;
if(elements.empty()){
throw std::out_of_range("myStack is empty");
}
elements.pop_back();
}
void foo(){
myStack<int> intValues;
myStack<float> floatValues;
myStack<double> doubleValues;
intValues.push(4);
floatValues.push(5.5f);
try{
intValues.pop();
floatValues.pop();
doubleValues.pop(); // cause exception
} catch(std::exception const& e){
std::cout<<"\tException: "<<e.what()<<std::endl;
}
std::cout<<"\tdone"<<std::endl;
}
#pragma nofunctrace(main)
int main(){
foo();
}
xlC t2.cpp -qfunctrace+myStack:foo
enter function: name=_Z3foov file=t2.cpp line=56
enter function: name=_ZN7myStackIiE4pushERKi file=t2.cpp line=42
push(4)
exit function: name=_ZN7myStackIiE4pushERKi file=t2.cpp line=45. It took 3 seconds
enter function: name=_ZN7myStackIfE4pushERKf file=t2.cpp line=42
push(5.5)
exit function: name=_ZN7myStackIfE4pushERKf file=t2.cpp line=45. It took 3 seconds
enter function: name=_ZN7myStackIiE3popEv file=t2.cpp line=48
pop()
exit function: name=_ZN7myStackIiE3popEv file=t2.cpp line=54. It took 5 seconds
enter function: name=_ZN7myStackIfE3popEv file=t2.cpp line=48
pop()
exit function: name=_ZN7myStackIfE3popEv file=t2.cpp line=54. It took 5 seconds
enter function: name=_ZN7myStackIdE3popEv file=t2.cpp line=48
pop()
catch function: name=_Z3foov file=t2.cpp line=65. It took 21 seconds
Exception: myStack is empty
done
exit function: name=_Z3foov file=t2.cpp line=69. It took 21 seconds