stacktrace_riscv-inl.inc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Copyright 2021 The Abseil Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_
  15. #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_
  16. // Generate stack trace for riscv
  17. #include <sys/ucontext.h>
  18. #include "absl/base/config.h"
  19. #if defined(__linux__)
  20. #include <sys/mman.h>
  21. #include <ucontext.h>
  22. #include <unistd.h>
  23. #endif
  24. #include <atomic>
  25. #include <cassert>
  26. #include <cstdint>
  27. #include <iostream>
  28. #include "absl/base/attributes.h"
  29. #include "absl/debugging/internal/address_is_readable.h"
  30. #include "absl/debugging/internal/vdso_support.h"
  31. #include "absl/debugging/stacktrace.h"
  32. static const uintptr_t kUnknownFrameSize = 0;
  33. #if defined(__linux__)
  34. // Returns the address of the VDSO __kernel_rt_sigreturn function, if present.
  35. static const unsigned char *GetKernelRtSigreturnAddress() {
  36. constexpr uintptr_t kImpossibleAddress = 0;
  37. ABSL_CONST_INIT static std::atomic<uintptr_t> memoized(kImpossibleAddress);
  38. uintptr_t address = memoized.load(std::memory_order_relaxed);
  39. if (address != kImpossibleAddress) {
  40. return reinterpret_cast<const unsigned char *>(address);
  41. }
  42. address = reinterpret_cast<uintptr_t>(nullptr);
  43. #if ABSL_HAVE_VDSO_SUPPORT
  44. absl::debugging_internal::VDSOSupport vdso;
  45. if (vdso.IsPresent()) {
  46. absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info;
  47. // Symbol versioning pulled from arch/riscv/kernel/vdso/vdso.lds at v5.10.
  48. auto lookup = [&](int type) {
  49. return vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_4.15", type,
  50. &symbol_info);
  51. };
  52. if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) ||
  53. symbol_info.address == nullptr) {
  54. // Unexpected: VDSO is present, yet the expected symbol is missing or
  55. // null.
  56. assert(false && "VDSO is present, but doesn't have expected symbol");
  57. } else {
  58. if (reinterpret_cast<uintptr_t>(symbol_info.address) !=
  59. kImpossibleAddress) {
  60. address = reinterpret_cast<uintptr_t>(symbol_info.address);
  61. } else {
  62. assert(false && "VDSO returned invalid address");
  63. }
  64. }
  65. }
  66. #endif
  67. memoized.store(address, std::memory_order_relaxed);
  68. return reinterpret_cast<const unsigned char *>(address);
  69. }
  70. #endif // __linux__
  71. // Compute the size of a stack frame in [low..high). We assume that low < high.
  72. // Return size of kUnknownFrameSize.
  73. template <typename T>
  74. static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) {
  75. const char *low_char_ptr = reinterpret_cast<const char *>(low);
  76. const char *high_char_ptr = reinterpret_cast<const char *>(high);
  77. return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize;
  78. }
  79. // Given a pointer to a stack frame, locate and return the calling stackframe,
  80. // or return null if no stackframe can be found. Perform sanity checks (the
  81. // strictness of which is controlled by the boolean parameter
  82. // "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
  83. template <bool STRICT_UNWINDING, bool WITH_CONTEXT>
  84. ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
  85. ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
  86. static void ** NextStackFrame(void **old_frame_pointer, const void *uc) {
  87. // .
  88. // .
  89. // .
  90. // +-> +----------------+
  91. // | | return address |
  92. // | | previous fp |
  93. // | | ... |
  94. // | +----------------+ <-+
  95. // | | return address | |
  96. // +---|- previous fp | |
  97. // | ... | |
  98. // $fp ->|----------------+ |
  99. // | return address | |
  100. // | previous fp -|---+
  101. // $sp ->| ... |
  102. // +----------------+
  103. void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]);
  104. bool check_frame_size = true;
  105. #if defined(__linux__)
  106. if (WITH_CONTEXT && uc != nullptr) {
  107. // Check to see if next frame's return address is __kernel_rt_sigreturn.
  108. if (old_frame_pointer[-1] == GetKernelRtSigreturnAddress()) {
  109. const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);
  110. // old_frame_pointer is not suitable for unwinding, look at ucontext to
  111. // discover frame pointer before signal.
  112. //
  113. // RISCV ELF psABI has the frame pointer at x8/fp/s0.
  114. // -- RISCV psABI Table 18.2
  115. void **const pre_signal_frame_pointer =
  116. reinterpret_cast<void **>(ucv->uc_mcontext.__gregs[8]);
  117. // Check the alleged frame pointer is actually readable. This is to
  118. // prevent "double fault" in case we hit the first fault due to stack
  119. // corruption.
  120. if (!absl::debugging_internal::AddressIsReadable(
  121. pre_signal_frame_pointer))
  122. return nullptr;
  123. // Alleged frame pointer is readable, use it for further unwinding.
  124. new_frame_pointer = pre_signal_frame_pointer;
  125. // Skip frame size check if we return from a signal. We may be using an
  126. // alterate stack for signals.
  127. check_frame_size = false;
  128. }
  129. }
  130. #endif
  131. // The RISCV ELF psABI mandates that the stack pointer is always 16-byte
  132. // aligned.
  133. // FIXME(abdulras) this doesn't hold for ILP32E which only mandates a 4-byte
  134. // alignment.
  135. if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0)
  136. return nullptr;
  137. // Check frame size. In strict mode, we assume frames to be under 100,000
  138. // bytes. In non-strict mode, we relax the limit to 1MB.
  139. if (check_frame_size) {
  140. const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
  141. const uintptr_t frame_size =
  142. ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
  143. if (frame_size == kUnknownFrameSize || frame_size > max_size)
  144. return nullptr;
  145. }
  146. return new_frame_pointer;
  147. }
  148. template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
  149. ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
  150. ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
  151. static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
  152. const void *ucp, int *min_dropped_frames) {
  153. #if defined(__GNUC__)
  154. void **frame_pointer = reinterpret_cast<void **>(__builtin_frame_address(0));
  155. #else
  156. #error reading stack pointer not yet supported on this platform
  157. #endif
  158. skip_count++; // Skip the frame for this function.
  159. int n = 0;
  160. // The `frame_pointer` that is computed here points to the top of the frame.
  161. // The two words preceding the address are the return address and the previous
  162. // frame pointer. To find a PC value associated with the current frame, we
  163. // need to go down a level in the call chain. So we remember the return
  164. // address of the last frame seen. This does not work for the first stack
  165. // frame, which belongs to `UnwindImp()` but we skip the frame for
  166. // `UnwindImp()` anyway.
  167. void *prev_return_address = nullptr;
  168. while (frame_pointer && n < max_depth) {
  169. // The absl::GetStackFrames routine si called when we are in some
  170. // informational context (the failure signal handler for example). Use the
  171. // non-strict unwinding rules to produce a stack trace that is as complete
  172. // as possible (even if it contains a few bogus entries in some rare cases).
  173. void **next_frame_pointer =
  174. NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);
  175. if (skip_count > 0) {
  176. skip_count--;
  177. } else {
  178. result[n] = prev_return_address;
  179. if (IS_STACK_FRAMES) {
  180. sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer);
  181. }
  182. n++;
  183. }
  184. prev_return_address = frame_pointer[-1];
  185. frame_pointer = next_frame_pointer;
  186. }
  187. if (min_dropped_frames != nullptr) {
  188. // Implementation detail: we clamp the max of frames we are willing to
  189. // count, so as not to spend too much time in the loop below.
  190. const int kMaxUnwind = 200;
  191. int j = 0;
  192. for (; frame_pointer != nullptr && j < kMaxUnwind; j++) {
  193. frame_pointer =
  194. NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);
  195. }
  196. *min_dropped_frames = j;
  197. }
  198. return n;
  199. }
  200. namespace absl {
  201. ABSL_NAMESPACE_BEGIN
  202. namespace debugging_internal {
  203. bool StackTraceWorksForTest() { return true; }
  204. } // namespace debugging_internal
  205. ABSL_NAMESPACE_END
  206. } // namespace absl
  207. #endif