61 lines
1.2 KiB
C++
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);
|
|
}
|