forked from archibate/mallocvis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddr2sym.hpp
116 lines (107 loc) · 3.21 KB
/
addr2sym.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once
#include <string>
#if __unix__
# include <cxxabi.h>
# include <execinfo.h>
inline std::string addr2sym(void *addr) {
if (addr == nullptr) {
return "null";
}
char **strings = backtrace_symbols(&addr, 1);
if (strings == nullptr) {
return "???";
}
std::string ret = strings[0];
free(strings);
auto pos = ret.find('(');
if (pos != std::string::npos) {
auto pos2 = ret.find('+', pos);
if (pos2 != std::string::npos) {
auto pos3 = ret.find(')', pos2);
auto offset = ret.substr(pos2, pos3 - pos2);
if (pos2 != pos + 1) {
ret = ret.substr(pos + 1, pos2 - pos - 1);
char *demangled =
abi::__cxa_demangle(ret.data(), nullptr, nullptr, nullptr);
if (demangled) {
ret = demangled;
free(demangled);
} else {
ret += "()";
ret += offset;
}
} else {
ret = ret.substr(0, pos) + offset;
auto slash = ret.rfind('/');
if (slash != std::string::npos) {
ret = ret.substr(slash + 1);
}
}
}
}
return ret;
}
#elif _MSC_VER
# include <dbghelp.h>
# include <windows.h>
# include <stdio.h>
# pragma comment(lib, "dbghelp.lib")
extern "C" char *__unDName(char *, char const *, int, void *, void *, int);
inline std::string addr2sym(void *addr) {
if (addr == nullptr) {
return "null";
}
DWORD64 dwDisplacement;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (!SymFromAddr(GetCurrentProcess(), (DWORD64)addr, &dwDisplacement,
pSymbol)) {
char buf[64];
snprintf(buf, sizeof(buf), "0x%8llx", (DWORD64)addr);
return buf;
}
std::string name(pSymbol->Name);
// demangle
char undname[1024];
__unDName(undname, name.c_str() + 1, sizeof(undname), malloc, free, 0x2800);
name = undname;
return name;
}
#elif _WIN32
# include <dbghelp.h>
# include <windows.h>
# pragma comment(lib, "dbghelp.lib")
inline std::string addr2sym(void *addr) {
DWORD64 dwDisplacement;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (!SymFromAddr(GetCurrentProcess(), (DWORD64)addr, &dwDisplacement,
pSymbol)) {
return "???";
}
std::string name(pSymbol->Name);
// demangle
if (name.find("??") == 0) {
char undname[1024];
if (UnDecorateSymbolName(pSymbol->Name, undname, sizeof(undname),
UNDNAME_COMPLETE)) {
name = undname;
}
}
return name;
}
#else
# include <sstream>
inline std::string addr2sym(void *addr) {
if (addr == nullptr) {
return "null";
}
std::ostringstream oss;
oss << "0x" << std::hex << addr;
return oss.str();
}
#endif