// compile with: g++ -rdynamic -c -std=c++11 -o caller.o getcaller.cpp #include #include #define BT_BUF_SIZE 10 #include #include #include static int depth = 2; std::string demangle(std::string& in) { if(in.size() < 5) return in; if(in.find("_Z") > 0) return in; std::ostringstream out; std::istringstream is(in.substr(2)); bool first = true; while(is) { char c = is.peek(); while(c == 'N' || c == 'K') { is.get(); c = is.peek(); } unsigned int len = 0; is >> len; if(len == 0) break; if(!first) out << "::"; first = false; char* buf = new char[len+1]; buf[len] = '\0'; is.read(buf, len); out << buf; delete[] buf; } return out.str(); } std::string getCaller() { if(depth+1 > BT_BUF_SIZE) return "UNKNOWN"; void* buffer[BT_BUF_SIZE]; int nptrs = backtrace(buffer, BT_BUF_SIZE); char** strings = backtrace_symbols(buffer, nptrs); if (!strings) return "UNKNOWN"; std::string out(strings[depth]); free(strings); size_t startoffset = out.rfind('(')+1; size_t plusoffset = out.find('+', startoffset)-1; if(plusoffset == std::string::npos) return "UNKNOWN"; out = out.substr(startoffset, plusoffset-startoffset); return demangle(out); }