logging: rename the `DEBUG` log level to `DBG`
[folly.git] / folly / experimental / exception_tracer / StackTrace.cpp
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 #include <folly/experimental/exception_tracer/StackTrace.h>
18
19 #include <cassert>
20 #include <cstdlib>
21 #include <new>
22
23 #include <folly/experimental/symbolizer/StackTrace.h>
24
25 namespace folly {
26 namespace exception_tracer {
27
28 class StackTraceStack::Node : public StackTrace {
29  public:
30   static Node* allocate();
31   void deallocate();
32
33   Node* next;
34
35  private:
36   Node() : next(nullptr) {}
37   ~Node() {}
38 };
39
40 auto StackTraceStack::Node::allocate() -> Node* {
41   // Null pointer on error, please.
42   return new (std::nothrow) Node();
43 }
44
45 void StackTraceStack::Node::deallocate() {
46   delete this;
47 }
48
49 bool StackTraceStack::pushCurrent() {
50   checkGuard();
51   auto node = Node::allocate();
52   if (!node) {
53     // cannot allocate memory
54     return false;
55   }
56
57   ssize_t n = folly::symbolizer::getStackTrace(node->addresses, kMaxFrames);
58   if (n == -1) {
59     node->deallocate();
60     return false;
61   }
62   node->frameCount = n;
63
64   node->next = top_;
65   top_ = node;
66   return true;
67 }
68
69 bool StackTraceStack::pop() {
70   checkGuard();
71   if (!top_) {
72     return false;
73   }
74
75   auto node = top_;
76   top_ = node->next;
77   node->deallocate();
78   return true;
79 }
80
81 bool StackTraceStack::moveTopFrom(StackTraceStack& other) {
82   checkGuard();
83   if (!other.top_) {
84     return false;
85   }
86
87   auto node = other.top_;
88   other.top_ = node->next;
89   node->next = top_;
90   top_ = node;
91   return true;
92 }
93
94 void StackTraceStack::clear() {
95   checkGuard();
96   while (top_) {
97     pop();
98   }
99 }
100
101 StackTrace* StackTraceStack::top() {
102   checkGuard();
103   return top_;
104 }
105
106 StackTrace* StackTraceStack::next(StackTrace* p) {
107   checkGuard();
108   assert(p);
109   return static_cast<Node*>(p)->next;
110 }
111 } // namespace exception_tracer
112 } // namespace folly