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
#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