//===-- sanitizer_stacktrace.h ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file is shared between AddressSanitizer and ThreadSanitizer // run-time libraries. //===----------------------------------------------------------------------===// #ifndef SANITIZER_STACKTRACE_H #define SANITIZER_STACKTRACE_H #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" namespace __sanitizer { struct BufferedStackTrace; static const u32 kStackTraceMax = …; #if SANITIZER_LINUX && defined(__mips__) #define SANITIZER_CAN_FAST_UNWIND … #elif SANITIZER_WINDOWS #define SANITIZER_CAN_FAST_UNWIND … #else #define SANITIZER_CAN_FAST_UNWIND … #endif // Fast unwind is the only option on Mac for now; we will need to // revisit this macro when slow unwind works on Mac, see // https://github.com/google/sanitizers/issues/137 #if SANITIZER_APPLE #define SANITIZER_CAN_SLOW_UNWIND … #else #define SANITIZER_CAN_SLOW_UNWIND … #endif struct StackTrace { … }; // Performance-critical, must be in the header. ALWAYS_INLINE uptr StackTrace::GetPreviousInstructionPc(uptr pc) { … } // StackTrace that owns the buffer used to store the addresses. struct BufferedStackTrace : public StackTrace { … }; #if defined(__s390x__) static const uptr kFrameSize = 160; #elif defined(__s390__) static const uptr kFrameSize = 96; #else static const uptr kFrameSize = …; #endif // Check if given pointer points into allocated stack area. static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) { … } } // namespace __sanitizer // Use this macro if you want to print stack trace with the caller // of the current function in the top frame. #define GET_CALLER_PC_BP … #define GET_CALLER_PC_BP_SP … // Use this macro if you want to print stack trace with the current // function in the top frame. #define GET_CURRENT_PC_BP … #define GET_CURRENT_PC_BP_SP … // GET_CURRENT_PC() is equivalent to StackTrace::GetCurrentPc(). // Optimized x86 version is faster than GetCurrentPc because // it does not involve a function call, instead it reads RIP register. // Reads of RIP by an instruction return RIP pointing to the next // instruction, which is exactly what we want here, thus 0 offset. // It needs to be a macro because otherwise we will get the name // of this function on the top of most stacks. Attribute artificial // does not do what it claims to do, unfortunatley. And attribute // __nodebug__ is clang-only. If we would have an attribute that // would remove this function from debug info, we could simply make // StackTrace::GetCurrentPc() faster. #if defined(__x86_64__) #define GET_CURRENT_PC() … #else #define GET_CURRENT_PC … #endif #endif // SANITIZER_STACKTRACE_H