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