Delete ClassInfoHook
[hiphop-php.git] / hphp / util / abi-cxx.cpp
blob9399333c2e4349e3dfa99766ece95a7c597e7e72
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #include "hphp/util/abi-cxx.h"
18 #include <algorithm>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <memory>
23 #include <mutex>
24 #include <string>
25 #include <unordered_map>
27 #include <cxxabi.h>
28 #include <execinfo.h>
30 #include "folly/Format.h"
32 #include "hphp/util/functional.h"
34 namespace HPHP {
36 //////////////////////////////////////////////////////////////////////
38 namespace {
40 typedef std::lock_guard<std::mutex> G;
41 std::mutex nameCacheLock;
42 std::unordered_map<void*, std::string, pointer_hash<void>> nameCache;
46 //////////////////////////////////////////////////////////////////////
48 std::string getNativeFunctionName(void* codeAddr) {
50 G g(nameCacheLock);
51 auto it = nameCache.find(codeAddr);
52 if (it != end(nameCache)) return it->second;
55 void* buf[1] = {codeAddr};
56 char** symbols = backtrace_symbols(buf, 1);
57 std::string functionName;
58 if (symbols != nullptr) {
60 // the output from backtrace_symbols looks like this:
61 // ../path/hhvm/hhvm(_ZN4HPHP2VM6Transl17interpOneIterInitEv+0) [0x17cebe9]
63 // we first want to extract the mangled name from it to get this:
64 // _ZN4HPHP2VM6Transl17interpOneIterInitEv
66 // and then pass this to abi::__cxa_demangle to get the demanged name:
67 // HPHP::JIT::interpOneIterInit()
69 // Sometimes, though, backtrace_symbols can't find the function name
70 // and ends up giving us a blank managled name, like this:
71 // ../path/hhvm/hhvm() [0x17e4d01]
72 // or this: [0x7fffca800130]
74 char* start = strchr(*symbols, '(');
75 if (start) {
76 start++;
77 char* end = strchr(start, '+');
78 if (end != nullptr) {
79 functionName.assign(start, end);
80 int status;
81 char* demangledName = abi::__cxa_demangle(functionName.c_str(),
82 0, 0, &status);
83 SCOPE_EXIT { free(demangledName); };
84 if (status == 0) functionName.assign(demangledName);
89 // backtrace_symbols requires that we free the array of strings but not the
90 // strings themselves.
91 free(symbols);
92 if (functionName.empty()) functionName = folly::format("{}", codeAddr).str();
94 G g(nameCacheLock);
95 return nameCache[codeAddr] = functionName;
98 //////////////////////////////////////////////////////////////////////