Skip to content

Instantly share code, notes, and snippets.

@mostevercxz
Last active April 27, 2019 07:29
Show Gist options
  • Select an option

  • Save mostevercxz/05dcf840031a827dc91164f568953013 to your computer and use it in GitHub Desktop.

Select an option

Save mostevercxz/05dcf840031a827dc91164f568953013 to your computer and use it in GitHub Desktop.
How to trace all functions in a specific c/c++ file?
#include "ftrace_a.h"
#include <iostream>
#include <dlfcn.h> // dladdr
#include <cxxabi.h> // __cxa_demangle
#include <stdlib.h> // malloc, free
#include <string.h> // strlen
extern "C"
{
// This function must not be traced!!!
char* __attribute__((no_instrument_function))
get_demangle_name_by_address(void *addr)
{
Dl_info info;
if (dladdr(addr, &info)){
if (info.dli_sname){
char *demangled = nullptr;
int status = -1;
if (info.dli_sname[0] == '_')
{
demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
if (status == 0)
{
char *temp = (char*)malloc(strlen(demangled) * sizeof(char) + 1);
strncpy(temp, demangled, strlen(demangled));
free(demangled);
return temp;
}
}
char *temp = (char*)malloc(strlen(info.dli_sname) * sizeof(char) + 1);
strncpy(temp, info.dli_sname, strlen(info.dli_sname));
return temp;
}
}else{
return NULL;
}
}
void __attribute__((no_instrument_function))
__cyg_profile_func_enter(void *this_func, void *call_site)
{
// core dumped using std::cout
//std::cout << "----enter," << this_func <<call_site <<std::endl;
//printf("-----enter,%p,%p\n", this_func, call_site);
char *func_name = get_demangle_name_by_address(this_func);
char *caller_name = get_demangle_name_by_address(call_site);
if (func_name && caller_name){
printf("----function trace,enter,%s,called by %s\n", func_name, caller_name);
free(func_name);
free(caller_name);
} else {
printf("----function trace,enter,%p,called by %p\n", this_func, call_site);
}
}
void __attribute__((no_instrument_function))
__cyg_profile_func_exit(void *this_func, void *call_site)
{
// core dumped using std::cout
//std::cout << "----exit," << this_func <<call_site <<std::endl;
//printf("-----exit,%p,%p\n", this_func, call_site);
char *func_name = get_demangle_name_by_address(this_func);
char *caller_name = get_demangle_name_by_address(call_site);
if (func_name && caller_name){
printf("----function trace,exit,%s,called by %s\n", func_name, caller_name);
free(func_name);
free(caller_name);
} else {
printf("----function trace,exit,%p,called by %p\n", this_func, call_site);
}
}
}
void BagManager::OnLoop()
{
std::cout << "OnLoop" << std::endl;
CheckItemDisappear();
}
void BagManager::CheckItemDisappear()
{
std::cout << "CheckItemDisappear" << std::endl;
}
void BagManager::AddItem()
{
std::cout << "AddItem" << std::endl;
}
class BagManager{
public:
void OnLoop();
void CheckItemDisappear();
void AddItem();
};
#include <iostream>
#include "ftrace_a.h"
#include <unistd.h>
int main(int argc, char const* argv[])
{
BagManager bm;
int loopTimes = 0;
while (true)
{
if ((++loopTimes) % 10 == 0)
{
bm.AddItem();
}
bm.OnLoop();
sleep(1);
}
return 0;
}
#!/bin/bash
set -x
rm -f ftrace_a.o ftrace_b.o ftrace
g++ -finstrument-functions -g -g3 -rdynamic -c ftrace_a.cpp -o ftrace_a.o
g++ -g -g3 -rdynamic -c ftrace_b.cpp -o ftrace_b.o
g++ -finstrument-functions -g -g3 -rdynamic ftrace_a.o ftrace_b.o -o ftrace -ldl
./ftrace
----function trace,enter,0x562fb00e1484,called by 0x562fb00e15ed
----function trace,enter,0x562fb00e13ed,called by 0x562fb00e14aa
----function trace,exit,0x562fb00e13ed,called by 0x562fb00e14aa
----function trace,exit,0x562fb00e1484,called by 0x562fb00e15ed
----function trace,enter,BagManager::OnLoop(),called by main
OnLoop
----function trace,enter,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
CheckItemDisappear
----function trace,exit,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
----function trace,exit,BagManager::OnLoop(),called by main
----function trace,enter,BagManager::OnLoop(),called by main
OnLoop
----function trace,enter,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
CheckItemDisappear
----function trace,exit,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
----function trace,exit,BagManager::OnLoop(),called by main
----function trace,enter,BagManager::OnLoop(),called by main
OnLoop
----function trace,enter,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
CheckItemDisappear
----function trace,exit,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
----function trace,exit,BagManager::OnLoop(),called by main
----function trace,enter,BagManager::OnLoop(),called by main
OnLoop
----function trace,enter,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
CheckItemDisappear
----function trace,exit,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
----function trace,exit,BagManager::OnLoop(),called by main
----function trace,enter,BagManager::OnLoop(),called by main
OnLoop
----function trace,enter,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
CheckItemDisappear
----function trace,exit,BagManager::CheckItemDisappear(),called by BagManager::OnLoop()
----function trace,exit,BagManager::OnLoop(),called by main
----function trace,enter,BagManager::OnLoop(),called by main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment