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