You can instruct the compiler to inserts calls to user-defined tracing functions to aid in debugging or timing the execution of other functions.
#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();
}
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();
}
enter function: name=foo__Fv file=t.cpp line=53
enter function: name=push__7myStackXTi_FRCi file=t.cpp line=39
push(4)
exit function: name=push__7myStackXTi_FRCi file=t.cpp line=42. It took 3 seconds
enter function: name=push__7myStackXTf_FRCf file=t.cpp line=39
push(5.5)
exit function: name=push__7myStackXTf_FRCf file=t.cpp line=42. It took 3 seconds
enter function: name=pop__7myStackXTi_Fv file=t.cpp line=45
pop()
exit function: name=pop__7myStackXTi_Fv file=t.cpp line=51. It took 5 seconds
enter function: name=pop__7myStackXTf_Fv file=t.cpp line=45
pop()
exit function: name=pop__7myStackXTf_Fv file=t.cpp line=51. It took 5 seconds
enter function: name=pop__7myStackXTd_Fv file=t.cpp line=45
pop()
catch function: name=foo__Fv file=t.cpp line=62. It took 21 seconds
Exception: myStack is empty
done
exit function: name=foo__Fv file=t.cpp line=66. It took 21 seconds