Toplevel entrypoints for classes/traits/interfaces
[hiphop-php.git] / hphp / util / stack-trace.h
blob9b3b0421dc8768c4a73029fee0d093d97bcf1d23
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 +----------------------------------------------------------------------+
17 #pragma once
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <vector>
24 #include <folly/Range.h>
26 #include "hphp/util/compatibility.h"
27 #include "hphp/util/portability.h"
29 #ifndef _MSC_VER
30 #include <dlfcn.h>
31 #endif
33 namespace HPHP {
34 ////////////////////////////////////////////////////////////////////////////////
37 * An unsymbolized stack frame.
39 struct StackFrame {
40 explicit StackFrame(void* addr) : addr{addr} {}
42 void* addr{nullptr};
43 int lineno{0};
44 int offset{0};
48 * A StackFrame that has been symbolized with a filename and function name.
50 struct StackFrameExtra : StackFrame {
51 explicit StackFrameExtra(void* addr) : StackFrame(addr) {}
53 std::string toString() const;
55 std::string filename;
56 std::string funcname;
59 ////////////////////////////////////////////////////////////////////////////////
62 * Taking a stacktrace at current execution location. Do not use directly, use
63 * StackTrace or StackTraceNoHeap instead.
65 struct StackTraceBase {
66 static constexpr unsigned kMaxFrame = 175;
68 static bool Enabled;
69 static const char* const* FunctionBlacklist;
70 static unsigned FunctionBlacklistCount;
72 protected:
73 StackTraceBase();
76 ////////////////////////////////////////////////////////////////////////////////
78 struct StackTrace : StackTraceBase {
79 struct PerfMap {
80 void rebuild();
81 bool translate(StackFrameExtra*) const;
83 struct Range {
84 uintptr_t base;
85 uintptr_t past;
86 struct Cmp {
87 bool operator() (const Range& a, const Range& b) const {
88 return a.past <= b.base;
92 bool m_built = false;
93 std::map<Range,std::string,Range::Cmp> m_map;
96 //////////////////////////////////////////////////////////////////////////////
99 * Construct the current stacktrace if `trace' and Enabled are true,
100 * else an empty stacktrace.
102 explicit StackTrace(bool trace = true);
105 * Construct the current stacktrace even when Enabled is false.
107 enum Force {};
108 explicit StackTrace(Force);
111 * Construct a stacktrace from a list of instruction pointers.
113 StackTrace(void* const* ips, size_t count);
116 * Constructing from hexEncode() results.
118 explicit StackTrace(folly::StringPiece);
121 * Translate a frame pointer to file name and line number pair.
123 static std::shared_ptr<StackFrameExtra> Translate(void* addr,
124 PerfMap* pm = nullptr);
127 * Encode the stacktrace addresses in a string.
129 * Skip minLevel frames, and end after the maxLevel'th at the most.
131 std::string hexEncode(int minLevel = 0, int maxLevel = 999) const;
134 * Generate a string representation of the stack trace.
136 const std::string& toString(int skip = 0, int limit = -1) const;
139 * Get translated frames.
141 void get(std::vector<std::shared_ptr<StackFrameExtra>>&) const;
143 //////////////////////////////////////////////////////////////////////////////
145 private:
146 std::vector<void*> m_frames;
148 // Cached backtrace string.
149 mutable std::string m_trace;
150 mutable bool m_trace_usable{false};
153 ////////////////////////////////////////////////////////////////////////////////
156 * Computing a stack trace without using the heap. Ideally this should be safe
157 * to use within a signal handler.
159 struct StackTraceNoHeap : StackTraceBase {
161 * Construct the curent stacktrace if `trace' is true, else an empty
162 * stacktrace.
164 explicit StackTraceNoHeap(bool trace = true);
167 * Log process/thread information, plus any extra logging that was queued.
169 void log(const char* errorType, int fd, const char* buildId,
170 int debuggerCount) const;
173 * Log the C++ stack trace
175 void printStackTrace(int fd) const;
178 * Add extra information to log together with a crash stacktrace log.
180 static void AddExtraLogging(const char* name, const std::string& value);
181 static void ClearAllExtraLogging();
183 struct ExtraLoggingClearer {
184 ExtraLoggingClearer() {}
185 ~ExtraLoggingClearer() {
186 StackTraceNoHeap::ClearAllExtraLogging();
190 private:
191 void* m_frames[kMaxFrame];
192 unsigned m_frame_count;
195 ////////////////////////////////////////////////////////////////////////////////