1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_DEBUG_STACK_TRACE_H_ 6 #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_DEBUG_STACK_TRACE_H_ 7 8 #include <cstddef> 9 #include <cstdint> 10 11 #include "build/build_config.h" 12 #include "partition_alloc/partition_alloc_base/component_export.h" 13 #include "partition_alloc/partition_alloc_base/debug/debugging_buildflags.h" 14 15 namespace partition_alloc::internal::base::debug { 16 17 // Returns end of the stack, or 0 if we couldn't get it. 18 #if BUILDFLAG(PA_CAN_UNWIND_WITH_FRAME_POINTERS) 19 PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 20 uintptr_t GetStackEnd(); 21 #endif 22 23 // Record a stack trace with up to |count| frames into |trace|. Returns the 24 // number of frames read. 25 PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 26 size_t CollectStackTrace(const void** trace, size_t count); 27 28 PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 29 void PrintStackTrace(const void** trace, size_t count); 30 31 #if BUILDFLAG(IS_POSIX) 32 PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 33 void OutputStackTrace(unsigned index, 34 uintptr_t address, 35 uintptr_t base_address, 36 const char* module_name, 37 uintptr_t offset); 38 #endif 39 40 #if BUILDFLAG(PA_CAN_UNWIND_WITH_FRAME_POINTERS) 41 42 // For stack scanning to be efficient it's very important for the thread to 43 // be started by Chrome. In that case we naturally terminate unwinding once 44 // we reach the origin of the stack (i.e. GetStackEnd()). If the thread is 45 // not started by Chrome (e.g. Android's main thread), then we end up always 46 // scanning area at the origin of the stack, wasting time and not finding any 47 // frames (since Android libraries don't have frame pointers). Scanning is not 48 // enabled on other posix platforms due to legacy reasons. 49 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 50 constexpr bool kEnableScanningByDefault = true; 51 #else 52 constexpr bool kEnableScanningByDefault = false; 53 #endif 54 55 // Traces the stack by using frame pointers. This function is faster but less 56 // reliable than StackTrace. It should work for debug and profiling builds, 57 // but not for release builds (although there are some exceptions). 58 // 59 // Writes at most |max_depth| frames (instruction pointers) into |out_trace| 60 // after skipping |skip_initial| frames. Note that the function itself is not 61 // added to the trace so |skip_initial| should be 0 in most cases. 62 // Returns number of frames written. |enable_scanning| enables scanning on 63 // platforms that do not enable scanning by default. 64 PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 65 size_t TraceStackFramePointers(const void** out_trace, 66 size_t max_depth, 67 size_t skip_initial, 68 bool enable_scanning = kEnableScanningByDefault); 69 70 #endif // BUILDFLAG(PA_CAN_UNWIND_WITH_FRAME_POINTERS) 71 72 } // namespace partition_alloc::internal::base::debug 73 74 #endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_DEBUG_STACK_TRACE_H_ 75