Add logging for comparison behaviors
[hiphop-php.git] / hphp / util / stack-trace.h
blob8343758bd8dee0c0c0e87015c61a0c516ac10ef9
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 #ifndef incl_HPHP_STACKTRACE_H_
18 #define incl_HPHP_STACKTRACE_H_
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
25 #include <folly/Range.h>
27 #include "hphp/util/compatibility.h"
28 #include "hphp/util/portability.h"
30 #ifndef _MSC_VER
31 #include <dlfcn.h>
32 #endif
34 namespace HPHP {
35 ////////////////////////////////////////////////////////////////////////////////
38 * An unsymbolized stack frame.
40 struct StackFrame {
41 explicit StackFrame(void* addr) : addr{addr} {}
43 void* addr{nullptr};
44 int lineno{0};
45 int offset{0};
49 * A StackFrame that has been symbolized with a filename and function name.
51 struct StackFrameExtra : StackFrame {
52 explicit StackFrameExtra(void* addr) : StackFrame(addr) {}
54 std::string toString() const;
56 std::string filename;
57 std::string funcname;
60 ////////////////////////////////////////////////////////////////////////////////
63 * Taking a stacktrace at current execution location. Do not use directly, use
64 * StackTrace or StackTraceNoHeap instead.
66 struct StackTraceBase {
67 static constexpr unsigned kMaxFrame = 175;
69 static bool Enabled;
70 static const char* const* FunctionBlacklist;
71 static unsigned FunctionBlacklistCount;
73 protected:
74 StackTraceBase();
77 ////////////////////////////////////////////////////////////////////////////////
79 struct StackTrace : StackTraceBase {
80 struct PerfMap {
81 void rebuild();
82 bool translate(StackFrameExtra*) const;
84 struct Range {
85 uintptr_t base;
86 uintptr_t past;
87 struct Cmp {
88 bool operator() (const Range& a, const Range& b) const {
89 return a.past <= b.base;
93 bool m_built = false;
94 std::map<Range,std::string,Range::Cmp> m_map;
97 //////////////////////////////////////////////////////////////////////////////
100 * Construct the current stacktrace if `trace' and Enabled are true,
101 * else an empty stacktrace.
103 explicit StackTrace(bool trace = true);
106 * Construct the current stacktrace even when Enabled is false.
108 enum Force {};
109 explicit StackTrace(Force);
112 * Construct a stacktrace from a list of instruction pointers.
114 StackTrace(void* const* ips, size_t count);
117 * Constructing from hexEncode() results.
119 explicit StackTrace(folly::StringPiece);
122 * Translate a frame pointer to file name and line number pair.
124 static std::shared_ptr<StackFrameExtra> Translate(void* addr,
125 PerfMap* pm = nullptr);
128 * Encode the stacktrace addresses in a string.
130 * Skip minLevel frames, and end after the maxLevel'th at the most.
132 std::string hexEncode(int minLevel = 0, int maxLevel = 999) const;
135 * Generate a string representation of the stack trace.
137 const std::string& toString(int skip = 0, int limit = -1) const;
140 * Get translated frames.
142 void get(std::vector<std::shared_ptr<StackFrameExtra>>&) const;
144 //////////////////////////////////////////////////////////////////////////////
146 private:
147 std::vector<void*> m_frames;
149 // Cached backtrace string.
150 mutable std::string m_trace;
151 mutable bool m_trace_usable{false};
154 ////////////////////////////////////////////////////////////////////////////////
157 * Computing a stack trace without using the heap. Ideally this should be safe
158 * to use within a signal handler.
160 struct StackTraceNoHeap : StackTraceBase {
162 * Construct the curent stacktrace if `trace' is true, else an empty
163 * stacktrace.
165 explicit StackTraceNoHeap(bool trace = true);
168 * Log process/thread information, plus any extra logging that was queued.
170 void log(const char* errorType, int fd, const char* buildId,
171 int debuggerCount) const;
174 * Log the C++ stack trace
176 void printStackTrace(int fd) const;
179 * Add extra information to log together with a crash stacktrace log.
181 static void AddExtraLogging(const char* name, const std::string& value);
182 static void ClearAllExtraLogging();
184 struct ExtraLoggingClearer {
185 ExtraLoggingClearer() {}
186 ~ExtraLoggingClearer() {
187 StackTraceNoHeap::ClearAllExtraLogging();
191 private:
192 void* m_frames[kMaxFrame];
193 unsigned m_frame_count;
196 ////////////////////////////////////////////////////////////////////////////////
199 #endif