Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / profiler / stack_sampling_profiler_test_util.h
1 // Copyright 2019 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 BASE_PROFILER_STACK_SAMPLING_PROFILER_TEST_UTIL_H_
6 #define BASE_PROFILER_STACK_SAMPLING_PROFILER_TEST_UTIL_H_
7
8 #include <memory>
9 #include <string>
10 #include <vector>
11
12 #include "base/base_export.h"
13 #include "base/functional/callback.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/memory/raw_ptr_exclusion.h"
16 #include "base/native_library.h"
17 #include "base/profiler/frame.h"
18 #include "base/profiler/sampling_profiler_thread_token.h"
19 #include "base/profiler/stack_sampling_profiler.h"
20 #include "base/strings/string_piece.h"
21 #include "base/synchronization/waitable_event.h"
22 #include "base/threading/platform_thread.h"
23
24 namespace base {
25
26 class Unwinder;
27 class ModuleCache;
28
29 // A thread to target for profiling that will run the supplied closure.
30 class TargetThread : public PlatformThread::Delegate {
31  public:
32   explicit TargetThread(OnceClosure to_run);
33
34   TargetThread(const TargetThread&) = delete;
35   TargetThread& operator=(const TargetThread&) = delete;
36
37   ~TargetThread() override;
38
39   void Start();
40   void Join();
41
42   // PlatformThread::Delegate:
43   void ThreadMain() override;
44
45   SamplingProfilerThreadToken thread_token() const { return thread_token_; }
46
47  private:
48   SamplingProfilerThreadToken thread_token_ = {0};
49   OnceClosure to_run_;
50   PlatformThreadHandle target_thread_handle_;
51 };
52
53 // Addresses near the start and end of a function.
54 struct FunctionAddressRange {
55   // This field is not a raw_ptr<> because it was filtered by the rewriter for:
56   // #in-out-param-ref
57   RAW_PTR_EXCLUSION const void* start;
58   raw_ptr<const void> end;
59 };
60
61 // Represents a stack unwind scenario to be sampled by the
62 // StackSamplingProfiler.
63 class UnwindScenario {
64  public:
65   // A callback provided by the caller that sets up the unwind scenario, then
66   // calls into the passed closure to wait for a sample to be taken. Returns the
67   // address range of the function that sets up the unwind scenario. The passed
68   // closure will be null when invoked solely to obtain the address range.
69   using SetupFunction = RepeatingCallback<FunctionAddressRange(OnceClosure)>;
70
71   // Events to coordinate the sampling.
72   struct SampleEvents {
73     WaitableEvent ready_for_sample;
74     WaitableEvent sample_finished;
75   };
76
77   explicit UnwindScenario(const SetupFunction& setup_function);
78   ~UnwindScenario();
79
80   UnwindScenario(const UnwindScenario&) = delete;
81   UnwindScenario& operator=(const UnwindScenario&) = delete;
82
83   // The address range of the innermost function that waits for the sample.
84   FunctionAddressRange GetWaitForSampleAddressRange() const;
85
86   // The address range of the provided setup function.
87   FunctionAddressRange GetSetupFunctionAddressRange() const;
88
89   // The address range of the outer function that indirectly invokes the setup
90   // function.
91   FunctionAddressRange GetOuterFunctionAddressRange() const;
92
93   // Executes the scenario.
94   void Execute(SampleEvents* events);
95
96  private:
97   static FunctionAddressRange InvokeSetupFunction(
98       const SetupFunction& setup_function,
99       SampleEvents* events);
100
101   static FunctionAddressRange WaitForSample(SampleEvents* events);
102
103   const SetupFunction setup_function_;
104 };
105
106 class TestModule : public ModuleCache::Module {
107  public:
108   explicit TestModule(uintptr_t base_address = 0,
109                       size_t size = 0,
110                       bool is_native = true)
111       : base_address_(base_address), size_(size), is_native_(is_native) {}
112
113   uintptr_t GetBaseAddress() const override;
114   std::string GetId() const override;
115   FilePath GetDebugBasename() const override;
116   size_t GetSize() const override;
117   bool IsNative() const override;
118
119   void set_id(const std::string& id) { id_ = id; }
120   void set_debug_basename(const FilePath& basename) {
121     debug_basename_ = basename;
122   }
123
124  private:
125   const uintptr_t base_address_;
126   const size_t size_;
127   const bool is_native_;
128   std::string id_;
129   FilePath debug_basename_;
130 };
131
132 bool operator==(const Frame& a, const Frame& b);
133
134 // UnwindScenario setup function that calls into |wait_for_sample| without doing
135 // any special unwinding setup, to exercise the "normal" unwind scenario.
136 FunctionAddressRange CallWithPlainFunction(OnceClosure wait_for_sample);
137
138 // Calls into |wait_for_sample| after using alloca(), to test unwinding with a
139 // frame pointer.
140 FunctionAddressRange CallWithAlloca(OnceClosure wait_for_sample);
141
142 // Calls into |wait_for_sample| through a function within another library, to
143 // test unwinding through multiple modules and scenarios involving unloaded
144 // modules.
145 FunctionAddressRange CallThroughOtherLibrary(NativeLibrary library,
146                                              OnceClosure wait_for_sample);
147
148 // The callback to perform profiling on the provided thread.
149 using ProfileCallback = OnceCallback<void(SamplingProfilerThreadToken)>;
150
151 // Executes |profile_callback| while running |scenario| on the target
152 // thread. Performs all necessary target thread startup and shutdown work before
153 // and afterward.
154 void WithTargetThread(UnwindScenario* scenario,
155                       ProfileCallback profile_callback);
156
157 using UnwinderFactory = OnceCallback<std::unique_ptr<Unwinder>()>;
158
159 // Returns the sample seen when taking one sample of |scenario|.
160 std::vector<Frame> SampleScenario(
161     UnwindScenario* scenario,
162     ModuleCache* module_cache,
163     UnwinderFactory aux_unwinder_factory = UnwinderFactory());
164
165 // Formats a sample into a string that can be output for test diagnostics.
166 std::string FormatSampleForDiagnosticOutput(const std::vector<Frame>& sample);
167
168 // Expects that the stack contains the functions with the specified address
169 // ranges, in the specified order.
170 void ExpectStackContains(const std::vector<Frame>& stack,
171                          const std::vector<FunctionAddressRange>& functions);
172
173 // Expects that the stack contains the function names in the specified order.
174 void ExpectStackContainsNames(const std::vector<Frame>& stack,
175                               const std::vector<std::string>& function_names);
176
177 // Expects that the stack does not contain the functions with the specified
178 // address ranges.
179 void ExpectStackDoesNotContain(
180     const std::vector<Frame>& stack,
181     const std::vector<FunctionAddressRange>& functions);
182
183 // Load test library with given name.
184 NativeLibrary LoadTestLibrary(StringPiece library_name);
185
186 // Loads the other library, which defines a function to be called in the
187 // WITH_OTHER_LIBRARY configuration.
188 NativeLibrary LoadOtherLibrary();
189
190 uintptr_t GetAddressInOtherLibrary(NativeLibrary library);
191
192 // Creates a list of core unwinders required for StackSamplingProfilerTest.
193 // This is useful notably on Android, which requires ChromeUnwinderAndroid in
194 // addition to the native one.
195 StackSamplingProfiler::UnwindersFactory CreateCoreUnwindersFactoryForTesting(
196     ModuleCache* module_cache);
197
198 }  // namespace base
199
200 #endif  // BASE_PROFILER_STACK_SAMPLING_PROFILER_TEST_UTIL_H_