StackTrace.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright 2012-present 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. #pragma once
  17. #include <cassert>
  18. #include <cstddef>
  19. #include <cstdint>
  20. namespace folly {
  21. namespace exception_tracer {
  22. constexpr size_t kMaxFrames = 500;
  23. struct StackTrace {
  24. StackTrace() : frameCount(0) {}
  25. size_t frameCount;
  26. uintptr_t addresses[kMaxFrames];
  27. };
  28. // note: no constructor so this can be __thread.
  29. // A StackTraceStack MUST be placed in zero-initialized memory.
  30. class StackTraceStack {
  31. class Node;
  32. public:
  33. /**
  34. * Push the current stack trace onto the stack.
  35. * Returns false on failure (not enough memory, getting stack trace failed),
  36. * true on success.
  37. */
  38. bool pushCurrent();
  39. /**
  40. * Pop the top stack trace from the stack.
  41. * Returns true on success, false on failure (stack was empty).
  42. */
  43. bool pop();
  44. /**
  45. * Move the top stack trace from other onto this.
  46. * Returns true on success, false on failure (other was empty).
  47. */
  48. bool moveTopFrom(StackTraceStack& other);
  49. /**
  50. * Clear the stack.
  51. */
  52. void clear();
  53. /**
  54. * Is the stack empty?
  55. */
  56. bool empty() const {
  57. return !top_;
  58. }
  59. /**
  60. * Return the top stack trace, or nullptr if the stack is empty.
  61. */
  62. StackTrace* top();
  63. /**
  64. * Return the stack trace following p, or nullptr if p is the bottom of
  65. * the stack.
  66. */
  67. StackTrace* next(StackTrace* p);
  68. private:
  69. // In debug mode, we assert that we're in zero-initialized memory by
  70. // checking that the two guards around top_ are zero.
  71. void checkGuard() const {
  72. #ifndef NDEBUG
  73. assert(guard1_ == 0 && guard2_ == 0);
  74. #endif
  75. }
  76. #ifndef NDEBUG
  77. uintptr_t guard1_;
  78. #endif
  79. Node* top_;
  80. #ifndef NDEBUG
  81. uintptr_t guard2_;
  82. #endif
  83. };
  84. } // namespace exception_tracer
  85. } // namespace folly