strace/getcaller.cpp

61 lines
1.2 KiB
C++

// compile with: g++ -rdynamic -c -std=c++11 -o caller.o getcaller.cpp
#include <string>
#include <execinfo.h>
#define BT_BUF_SIZE 10
#include <memory.h>
#include <stdlib.h>
#include <sstream>
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);
}