2017
[folly.git] / folly / experimental / exception_tracer / StackTrace.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <cassert>
20 #include <cstddef>
21 #include <cstdint>
22
23 namespace folly { namespace exception_tracer {
24
25 constexpr size_t kMaxFrames = 500;
26
27 struct StackTrace {
28   StackTrace() : frameCount(0) { }
29
30   size_t frameCount;
31   uintptr_t addresses[kMaxFrames];
32 };
33
34 // note: no constructor so this can be __thread.
35 // A StackTraceStack MUST be placed in zero-initialized memory.
36 class StackTraceStack {
37   class Node;
38  public:
39   /**
40    * Push the current stack trace onto the stack.
41    * Returns false on failure (not enough memory, getting stack trace failed),
42    * true on success.
43    */
44   bool pushCurrent();
45
46   /**
47    * Pop the top stack trace from the stack.
48    * Returns true on success, false on failure (stack was empty).
49    */
50   bool pop();
51
52   /**
53    * Move the top stack trace from other onto this.
54    * Returns true on success, false on failure (other was empty).
55    */
56   bool moveTopFrom(StackTraceStack& other);
57
58   /**
59    * Clear the stack.
60    */
61
62   void clear();
63
64   /**
65    * Is the stack empty?
66    */
67   bool empty() const { return !top_; }
68
69   /**
70    * Return the top stack trace, or nullptr if the stack is empty.
71    */
72   StackTrace* top();
73
74   /**
75    * Return the stack trace following p, or nullptr if p is the bottom of
76    * the stack.
77    */
78   StackTrace* next(StackTrace* p);
79
80  private:
81   // In debug mode, we assert that we're in zero-initialized memory by
82   // checking that the two guards around top_ are zero.
83   void checkGuard() const {
84 #ifndef NDEBUG
85     assert(guard1_ == 0 && guard2_ == 0);
86 #endif
87   }
88
89 #ifndef NDEBUG
90   uintptr_t guard1_;
91 #endif
92   Node* top_;
93 #ifndef NDEBUG
94   uintptr_t guard2_;
95 #endif
96 };
97
98 }}  // namespaces