asan_stack.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //===-- asan_stack.cpp ----------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of AddressSanitizer, an address sanity checker.
  10. //
  11. // Code for ASan stack trace.
  12. //===----------------------------------------------------------------------===//
  13. #include "asan_internal.h"
  14. #include "asan_stack.h"
  15. #include "sanitizer_common/sanitizer_atomic.h"
  16. namespace __asan {
  17. static atomic_uint32_t malloc_context_size;
  18. void SetMallocContextSize(u32 size) {
  19. atomic_store(&malloc_context_size, size, memory_order_release);
  20. }
  21. u32 GetMallocContextSize() {
  22. return atomic_load(&malloc_context_size, memory_order_acquire);
  23. }
  24. namespace {
  25. // ScopedUnwinding is a scope for stacktracing member of a context
  26. class ScopedUnwinding {
  27. public:
  28. explicit ScopedUnwinding(AsanThread *t) : thread(t) {
  29. if (thread) {
  30. can_unwind = !thread->isUnwinding();
  31. thread->setUnwinding(true);
  32. }
  33. }
  34. ~ScopedUnwinding() {
  35. if (thread)
  36. thread->setUnwinding(false);
  37. }
  38. bool CanUnwind() const { return can_unwind; }
  39. private:
  40. AsanThread *thread = nullptr;
  41. bool can_unwind = true;
  42. };
  43. } // namespace
  44. } // namespace __asan
  45. void __sanitizer::BufferedStackTrace::UnwindImpl(
  46. uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
  47. using namespace __asan;
  48. size = 0;
  49. if (UNLIKELY(!asan_inited))
  50. return;
  51. request_fast = StackTrace::WillUseFastUnwind(request_fast);
  52. AsanThread *t = GetCurrentThread();
  53. ScopedUnwinding unwind_scope(t);
  54. if (!unwind_scope.CanUnwind())
  55. return;
  56. if (request_fast) {
  57. if (t) {
  58. Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
  59. true);
  60. }
  61. return;
  62. }
  63. if (SANITIZER_MIPS && t &&
  64. !IsValidFrame(bp, t->stack_top(), t->stack_bottom()))
  65. return;
  66. Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0,
  67. t ? t->stack_bottom() : 0, false);
  68. }
  69. // ------------------ Interface -------------- {{{1
  70. extern "C" {
  71. SANITIZER_INTERFACE_ATTRIBUTE
  72. void __sanitizer_print_stack_trace() {
  73. using namespace __asan;
  74. PRINT_CURRENT_STACK();
  75. }
  76. } // extern "C"