统计函数被调用次数和对应位置及堆栈

自己实现 setenv , 然后输出堆栈, 根据堆栈输出. 定位哪儿调用了setenv 函数; 同理可以定位哪些全局变量; __cxa_atexit 可以定位哪些cpp全局变量 static变量, 即 data segment中的一些变量, 确认变量地址;

// #define _GNU_SOURCE
#include 
#include 


typedef unsigned int uint;

struct BacktraceState
{
   void** current;
   void** end;
};

static _Unwind_Reason_Code unwind_backtrace(struct _Unwind_Context* context, void* arg)
{
   struct  BacktraceState* state = (struct BacktraceState*)(arg);
   _Unwind_Word pc = _Unwind_GetIP(context);
   if (pc) {
       if (state->current == state->end) {
           return _URC_END_OF_STACK;
       } else {
           *state->current++ = (void*)(pc);
       }
   }
   return _URC_NO_REASON;
}

static uint backtrace(void** buffer, uint max)
{
   struct BacktraceState state = {buffer, buffer + max};
   _Unwind_Backtrace(unwind_backtrace, &state);
   return state.current - buffer;
}

static void backtrace2offset(void** buffer, uint buffer_len) {
    Dl_info info;
    for(uint i = 0; i < buffer_len; i++) {
        dladdr(buffer[i],&info);
        buffer[i] = (void*)((char*)buffer[i] - (char*)info.dli_fbase);
    }
}

extern "C" {
  int setenv(const char *, const char *, int) {
    void *s[30] = {0};
    int n = backtrace(s, sizeof(s)/sizeof(*s));
    backtrace2offset(s, n);
    for(int i = 0; i<n ; i++) LOGD("chen deug %p", s[i]);
    return 0;
  }
}

你可能感兴趣的:(C/C++,开发语言)