Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / profiler / stack_sampling_profiler_unittest.cc
1 // Copyright 2015 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 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <cstdlib>
9 #include <memory>
10 #include <set>
11 #include <utility>
12 #include <vector>
13
14 #include "base/compiler_specific.h"
15 #include "base/files/file_util.h"
16 #include "base/functional/bind.h"
17 #include "base/functional/callback.h"
18 #include "base/location.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/memory/raw_ptr.h"
21 #include "base/metrics/metrics_hashes.h"
22 #include "base/profiler/profiler_buildflags.h"
23 #include "base/profiler/sample_metadata.h"
24 #include "base/profiler/stack_sampler.h"
25 #include "base/profiler/stack_sampling_profiler.h"
26 #include "base/profiler/stack_sampling_profiler_test_util.h"
27 #include "base/profiler/unwinder.h"
28 #include "base/ranges/algorithm.h"
29 #include "base/run_loop.h"
30 #include "base/scoped_native_library.h"
31 #include "base/strings/utf_string_conversions.h"
32 #include "base/synchronization/lock.h"
33 #include "base/synchronization/waitable_event.h"
34 #include "base/test/bind.h"
35 #include "base/threading/simple_thread.h"
36 #include "base/time/time.h"
37 #include "build/build_config.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39
40 #if BUILDFLAG(IS_WIN)
41 #include <intrin.h>
42 #include <malloc.h>
43 #include <windows.h>
44 #else
45 #include <alloca.h>
46 #endif
47
48 // STACK_SAMPLING_PROFILER_SUPPORTED is used to conditionally enable the tests
49 // below for supported platforms (currently Win x64, Mac x64, iOS 64, some
50 // Android, and ChromeOS x64).
51 // ChromeOS: These don't run under MSan because parts of the stack aren't
52 // initialized.
53 #if (BUILDFLAG(IS_WIN) && defined(ARCH_CPU_X86_64)) ||            \
54     (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_X86_64)) ||            \
55     (BUILDFLAG(IS_IOS) && defined(ARCH_CPU_64_BITS)) ||           \
56     (BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)) || \
57     (BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_X86_64) &&        \
58      !defined(MEMORY_SANITIZER))
59 #define STACK_SAMPLING_PROFILER_SUPPORTED 1
60 #endif
61
62 namespace base {
63
64 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
65 #define PROFILER_TEST_F(TestClass, TestName) TEST_F(TestClass, TestName)
66 #else
67 #define PROFILER_TEST_F(TestClass, TestName) \
68   TEST_F(TestClass, DISABLED_##TestName)
69 #endif
70
71 using SamplingParams = StackSamplingProfiler::SamplingParams;
72
73 namespace {
74
75 // State provided to the ProfileBuilder's ApplyMetadataRetrospectively function.
76 struct RetrospectiveMetadata {
77   TimeTicks period_start;
78   TimeTicks period_end;
79   MetadataRecorder::Item item;
80 };
81
82 // Profile consists of a set of samples and other sampling information.
83 struct Profile {
84   // The collected samples.
85   std::vector<std::vector<Frame>> samples;
86
87   // The number of invocations of RecordMetadata().
88   int record_metadata_count;
89
90   // The retrospective metadata requests.
91   std::vector<RetrospectiveMetadata> retrospective_metadata;
92
93   // The profile metadata requests.
94   std::vector<MetadataRecorder::Item> profile_metadata;
95
96   // Duration of this profile.
97   TimeDelta profile_duration;
98
99   // Time between samples.
100   TimeDelta sampling_period;
101 };
102
103 // The callback type used to collect a profile. The passed Profile is move-only.
104 // Other threads, including the UI thread, may block on callback completion so
105 // this should run as quickly as possible.
106 using ProfileCompletedCallback = OnceCallback<void(Profile)>;
107
108 // TestProfileBuilder collects samples produced by the profiler.
109 class TestProfileBuilder : public ProfileBuilder {
110  public:
111   TestProfileBuilder(ModuleCache* module_cache,
112                      ProfileCompletedCallback callback);
113
114   TestProfileBuilder(const TestProfileBuilder&) = delete;
115   TestProfileBuilder& operator=(const TestProfileBuilder&) = delete;
116
117   ~TestProfileBuilder() override;
118
119   // ProfileBuilder:
120   ModuleCache* GetModuleCache() override;
121   void RecordMetadata(
122       const MetadataRecorder::MetadataProvider& metadata_provider) override;
123   void ApplyMetadataRetrospectively(
124       TimeTicks period_start,
125       TimeTicks period_end,
126       const MetadataRecorder::Item& item) override;
127   void AddProfileMetadata(const MetadataRecorder::Item& item) override;
128   void OnSampleCompleted(std::vector<Frame> sample,
129                          TimeTicks sample_timestamp) override;
130   void OnProfileCompleted(TimeDelta profile_duration,
131                           TimeDelta sampling_period) override;
132
133  private:
134   raw_ptr<ModuleCache> module_cache_;
135
136   // The set of recorded samples.
137   std::vector<std::vector<Frame>> samples_;
138
139   // The number of invocations of RecordMetadata().
140   int record_metadata_count_ = 0;
141
142   // The retrospective metadata requests.
143   std::vector<RetrospectiveMetadata> retrospective_metadata_;
144
145   // The profile metadata requests.
146   std::vector<MetadataRecorder::Item> profile_metadata_;
147
148   // Callback made when sampling a profile completes.
149   ProfileCompletedCallback callback_;
150 };
151
152 TestProfileBuilder::TestProfileBuilder(ModuleCache* module_cache,
153                                        ProfileCompletedCallback callback)
154     : module_cache_(module_cache), callback_(std::move(callback)) {}
155
156 TestProfileBuilder::~TestProfileBuilder() = default;
157
158 ModuleCache* TestProfileBuilder::GetModuleCache() {
159   return module_cache_;
160 }
161
162 void TestProfileBuilder::RecordMetadata(
163     const MetadataRecorder::MetadataProvider& metadata_provider) {
164   ++record_metadata_count_;
165 }
166
167 void TestProfileBuilder::ApplyMetadataRetrospectively(
168     TimeTicks period_start,
169     TimeTicks period_end,
170     const MetadataRecorder::Item& item) {
171   retrospective_metadata_.push_back(
172       RetrospectiveMetadata{period_start, period_end, item});
173 }
174
175 void TestProfileBuilder::AddProfileMetadata(
176     const MetadataRecorder::Item& item) {
177   profile_metadata_.push_back(item);
178 }
179
180 void TestProfileBuilder::OnSampleCompleted(std::vector<Frame> sample,
181                                            TimeTicks sample_timestamp) {
182   samples_.push_back(std::move(sample));
183 }
184
185 void TestProfileBuilder::OnProfileCompleted(TimeDelta profile_duration,
186                                             TimeDelta sampling_period) {
187   std::move(callback_).Run(Profile{samples_, record_metadata_count_,
188                                    retrospective_metadata_, profile_metadata_,
189                                    profile_duration, sampling_period});
190 }
191
192 // Unloads |library| and returns when it has completed unloading. Unloading a
193 // library is asynchronous on Windows, so simply calling UnloadNativeLibrary()
194 // is insufficient to ensure it's been unloaded.
195 void SynchronousUnloadNativeLibrary(NativeLibrary library) {
196   UnloadNativeLibrary(library);
197 #if BUILDFLAG(IS_WIN)
198   // NativeLibrary is a typedef for HMODULE, which is actually the base address
199   // of the module.
200   uintptr_t module_base_address = reinterpret_cast<uintptr_t>(library);
201   HMODULE module_handle;
202   // Keep trying to get the module handle until the call fails.
203   while (::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
204                                  GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
205                              reinterpret_cast<LPCTSTR>(module_base_address),
206                              &module_handle) ||
207          ::GetLastError() != ERROR_MOD_NOT_FOUND) {
208     PlatformThread::Sleep(Milliseconds(1));
209   }
210 #elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
211 // Unloading a library on Mac and Android is synchronous.
212 #else
213   NOTIMPLEMENTED();
214 #endif
215 }
216
217 void WithTargetThread(ProfileCallback profile_callback) {
218   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
219   WithTargetThread(&scenario, std::move(profile_callback));
220 }
221
222 struct TestProfilerInfo {
223   TestProfilerInfo(SamplingProfilerThreadToken thread_token,
224                    const SamplingParams& params,
225                    ModuleCache* module_cache,
226                    StackSamplerTestDelegate* delegate = nullptr)
227       : completed(WaitableEvent::ResetPolicy::MANUAL,
228                   WaitableEvent::InitialState::NOT_SIGNALED),
229         profiler(thread_token,
230                  params,
231                  std::make_unique<TestProfileBuilder>(
232                      module_cache,
233                      BindLambdaForTesting([this](Profile result_profile) {
234                        profile = std::move(result_profile);
235                        completed.Signal();
236                      })),
237                  CreateCoreUnwindersFactoryForTesting(module_cache),
238                  RepeatingClosure(),
239                  delegate) {}
240
241   TestProfilerInfo(const TestProfilerInfo&) = delete;
242   TestProfilerInfo& operator=(const TestProfilerInfo&) = delete;
243
244   // The order here is important to ensure objects being referenced don't get
245   // destructed until after the objects referencing them.
246   Profile profile;
247   WaitableEvent completed;
248   StackSamplingProfiler profiler;
249 };
250
251 // Captures samples as specified by |params| on the TargetThread, and returns
252 // them. Waits up to |profiler_wait_time| for the profiler to complete.
253 std::vector<std::vector<Frame>> CaptureSamples(const SamplingParams& params,
254                                                TimeDelta profiler_wait_time,
255                                                ModuleCache* module_cache) {
256   std::vector<std::vector<Frame>> samples;
257   WithTargetThread(BindLambdaForTesting(
258       [&](SamplingProfilerThreadToken target_thread_token) {
259         TestProfilerInfo info(target_thread_token, params, module_cache);
260         info.profiler.Start();
261         info.completed.TimedWait(profiler_wait_time);
262         info.profiler.Stop();
263         info.completed.Wait();
264         samples = std::move(info.profile.samples);
265       }));
266
267   return samples;
268 }
269
270 // Waits for one of multiple samplings to complete.
271 size_t WaitForSamplingComplete(
272     const std::vector<std::unique_ptr<TestProfilerInfo>>& infos) {
273   // Map unique_ptrs to something that WaitMany can accept.
274   std::vector<WaitableEvent*> sampling_completed_rawptrs(infos.size());
275   ranges::transform(infos, sampling_completed_rawptrs.begin(),
276                     [](const std::unique_ptr<TestProfilerInfo>& info) {
277                       return &info.get()->completed;
278                     });
279   // Wait for one profiler to finish.
280   return WaitableEvent::WaitMany(sampling_completed_rawptrs.data(),
281                                  sampling_completed_rawptrs.size());
282 }
283
284 // Returns a duration that is longer than the test timeout. We would use
285 // TimeDelta::Max() but https://crbug.com/465948.
286 TimeDelta AVeryLongTimeDelta() {
287   return Days(1);
288 }
289
290 // Tests the scenario where the library is unloaded after copying the stack, but
291 // before walking it. If |wait_until_unloaded| is true, ensures that the
292 // asynchronous library loading has completed before walking the stack. If
293 // false, the unloading may still be occurring during the stack walk.
294 void TestLibraryUnload(bool wait_until_unloaded, ModuleCache* module_cache) {
295   // Test delegate that supports intervening between the copying of the stack
296   // and the walking of the stack.
297   class StackCopiedSignaler : public StackSamplerTestDelegate {
298    public:
299     StackCopiedSignaler(WaitableEvent* stack_copied,
300                         WaitableEvent* start_stack_walk,
301                         bool wait_to_walk_stack)
302         : stack_copied_(stack_copied),
303           start_stack_walk_(start_stack_walk),
304           wait_to_walk_stack_(wait_to_walk_stack) {}
305
306     void OnPreStackWalk() override {
307       stack_copied_->Signal();
308       if (wait_to_walk_stack_)
309         start_stack_walk_->Wait();
310     }
311
312    private:
313     const raw_ptr<WaitableEvent> stack_copied_;
314     const raw_ptr<WaitableEvent> start_stack_walk_;
315     const bool wait_to_walk_stack_;
316   };
317
318   SamplingParams params;
319   params.sampling_interval = Milliseconds(0);
320   params.samples_per_profile = 1;
321
322   NativeLibrary other_library = LoadOtherLibrary();
323
324   UnwindScenario scenario(
325       BindRepeating(&CallThroughOtherLibrary, Unretained(other_library)));
326
327   UnwindScenario::SampleEvents events;
328   TargetThread target_thread(
329       BindLambdaForTesting([&]() { scenario.Execute(&events); }));
330   target_thread.Start();
331   events.ready_for_sample.Wait();
332
333   WaitableEvent sampling_thread_completed(
334       WaitableEvent::ResetPolicy::MANUAL,
335       WaitableEvent::InitialState::NOT_SIGNALED);
336   Profile profile;
337
338   WaitableEvent stack_copied(WaitableEvent::ResetPolicy::MANUAL,
339                              WaitableEvent::InitialState::NOT_SIGNALED);
340   WaitableEvent start_stack_walk(WaitableEvent::ResetPolicy::MANUAL,
341                                  WaitableEvent::InitialState::NOT_SIGNALED);
342   StackCopiedSignaler test_delegate(&stack_copied, &start_stack_walk,
343                                     wait_until_unloaded);
344   StackSamplingProfiler profiler(
345       target_thread.thread_token(), params,
346       std::make_unique<TestProfileBuilder>(
347           module_cache,
348           BindLambdaForTesting(
349               [&profile, &sampling_thread_completed](Profile result_profile) {
350                 profile = std::move(result_profile);
351                 sampling_thread_completed.Signal();
352               })),
353       CreateCoreUnwindersFactoryForTesting(module_cache), RepeatingClosure(),
354       &test_delegate);
355
356   profiler.Start();
357
358   // Wait for the stack to be copied and the target thread to be resumed.
359   stack_copied.Wait();
360
361   // Cause the target thread to finish, so that it's no longer executing code in
362   // the library we're about to unload.
363   events.sample_finished.Signal();
364   target_thread.Join();
365
366   // Unload the library now that it's not being used.
367   if (wait_until_unloaded)
368     SynchronousUnloadNativeLibrary(other_library);
369   else
370     UnloadNativeLibrary(other_library);
371
372   // Let the stack walk commence after unloading the library, if we're waiting
373   // on that event.
374   start_stack_walk.Signal();
375
376   // Wait for the sampling thread to complete and fill out |profile|.
377   sampling_thread_completed.Wait();
378
379   // Look up the sample.
380   ASSERT_EQ(1u, profile.samples.size());
381   const std::vector<Frame>& sample = profile.samples[0];
382
383   if (wait_until_unloaded) {
384     // We expect the stack to look something like this, with the frame in the
385     // now-unloaded library having a null module.
386     //
387     // ... WaitableEvent and system frames ...
388     // WaitForSample()
389     // TargetThread::OtherLibraryCallback
390     // <frame in unloaded library>
391     EXPECT_EQ(nullptr, sample.back().module)
392         << "Stack:\n"
393         << FormatSampleForDiagnosticOutput(sample);
394
395     ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange()});
396     ExpectStackDoesNotContain(sample,
397                               {scenario.GetSetupFunctionAddressRange(),
398                                scenario.GetOuterFunctionAddressRange()});
399   } else {
400     // We didn't wait for the asynchronous unloading to complete, so the results
401     // are non-deterministic: if the library finished unloading we should have
402     // the same stack as |wait_until_unloaded|, if not we should have the full
403     // stack. The important thing is that we should not crash.
404
405     if (!sample.back().module) {
406       // This is the same case as |wait_until_unloaded|.
407       ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange()});
408       ExpectStackDoesNotContain(sample,
409                                 {scenario.GetSetupFunctionAddressRange(),
410                                  scenario.GetOuterFunctionAddressRange()});
411       return;
412     }
413
414     ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange(),
415                                  scenario.GetSetupFunctionAddressRange(),
416                                  scenario.GetOuterFunctionAddressRange()});
417   }
418 }
419
420 // Provide a suitable (and clean) environment for the tests below. All tests
421 // must use this class to ensure that proper clean-up is done and thus be
422 // usable in a later test.
423 class StackSamplingProfilerTest : public testing::Test {
424  public:
425   void SetUp() override {
426     // The idle-shutdown time is too long for convenient (and accurate) testing.
427     // That behavior is checked instead by artificially triggering it through
428     // the TestPeer.
429     StackSamplingProfiler::TestPeer::DisableIdleShutdown();
430   }
431
432   void TearDown() override {
433     // Be a good citizen and clean up after ourselves. This also re-enables the
434     // idle-shutdown behavior.
435     StackSamplingProfiler::TestPeer::Reset();
436   }
437
438  protected:
439   ModuleCache* module_cache() { return &module_cache_; }
440
441  private:
442   ModuleCache module_cache_;
443 };
444
445 }  // namespace
446
447 // Checks that the basic expected information is present in sampled frames.
448 //
449 // macOS ASAN is not yet supported - crbug.com/718628.
450 //
451 // TODO(https://crbug.com/1100175): Enable this test again for Android with
452 // ASAN. This is now disabled because the android-asan bot fails.
453 //
454 // If we're running the ChromeOS unit tests on Linux, this test will never pass
455 // because Ubuntu's libc isn't compiled with frame pointers. Skip if not a real
456 // ChromeOS device.
457 #if (defined(ADDRESS_SANITIZER) && BUILDFLAG(IS_APPLE)) ||   \
458     (defined(ADDRESS_SANITIZER) && BUILDFLAG(IS_ANDROID)) || \
459     (BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_CHROMEOS_DEVICE))
460 #define MAYBE_Basic DISABLED_Basic
461 #else
462 #define MAYBE_Basic Basic
463 #endif
464 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Basic) {
465   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
466   const std::vector<Frame>& sample = SampleScenario(&scenario, module_cache());
467
468   // Check that all the modules are valid.
469   for (const auto& frame : sample)
470     EXPECT_NE(nullptr, frame.module);
471
472   // The stack should contain a full unwind.
473   ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange(),
474                                scenario.GetSetupFunctionAddressRange(),
475                                scenario.GetOuterFunctionAddressRange()});
476 }
477
478 // A simple unwinder that always generates one frame then aborts the stack walk.
479 class TestAuxUnwinder : public Unwinder {
480  public:
481   TestAuxUnwinder(const Frame& frame_to_report,
482                   base::RepeatingClosure add_initial_modules_callback)
483       : frame_to_report_(frame_to_report),
484         add_initial_modules_callback_(std::move(add_initial_modules_callback)) {
485   }
486
487   TestAuxUnwinder(const TestAuxUnwinder&) = delete;
488   TestAuxUnwinder& operator=(const TestAuxUnwinder&) = delete;
489
490   void InitializeModules() override {
491     if (add_initial_modules_callback_)
492       add_initial_modules_callback_.Run();
493   }
494   bool CanUnwindFrom(const Frame& current_frame) const override { return true; }
495
496   UnwindResult TryUnwind(RegisterContext* thread_context,
497                          uintptr_t stack_top,
498                          std::vector<Frame>* stack) override {
499     stack->push_back(frame_to_report_);
500     return UnwindResult::kAborted;
501   }
502
503  private:
504   const Frame frame_to_report_;
505   base::RepeatingClosure add_initial_modules_callback_;
506 };
507
508 // Checks that the profiler handles stacks containing dynamically-allocated
509 // stack memory.
510 // macOS ASAN is not yet supported - crbug.com/718628.
511 // Android is not supported since Chrome unwind tables don't support dynamic
512 // frames.
513 // If we're running the ChromeOS unit tests on Linux, this test will never pass
514 // because Ubuntu's libc isn't compiled with frame pointers. Skip if not a real
515 // ChromeOS device.
516 #if (defined(ADDRESS_SANITIZER) && BUILDFLAG(IS_APPLE)) || \
517     BUILDFLAG(IS_ANDROID) ||                               \
518     (BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_CHROMEOS_DEVICE))
519 #define MAYBE_Alloca DISABLED_Alloca
520 #else
521 #define MAYBE_Alloca Alloca
522 #endif
523 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) {
524   UnwindScenario scenario(BindRepeating(&CallWithAlloca));
525   const std::vector<Frame>& sample = SampleScenario(&scenario, module_cache());
526
527   // The stack should contain a full unwind.
528   ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange(),
529                                scenario.GetSetupFunctionAddressRange(),
530                                scenario.GetOuterFunctionAddressRange()});
531 }
532
533 // Checks that a stack that runs through another library produces a stack with
534 // the expected functions.
535 // macOS ASAN is not yet supported - crbug.com/718628.
536 // iOS chrome doesn't support loading native libraries.
537 // Android is not supported when EXCLUDE_UNWIND_TABLES |other_library| doesn't
538 // have unwind tables.
539 // TODO(https://crbug.com/1100175): Enable this test again for Android with
540 // ASAN. This is now disabled because the android-asan bot fails.
541 // If we're running the ChromeOS unit tests on Linux, this test will never pass
542 // because Ubuntu's libc isn't compiled with frame pointers. Skip if not a real
543 // ChromeOS device.
544 #if (defined(ADDRESS_SANITIZER) && BUILDFLAG(IS_APPLE)) ||         \
545     BUILDFLAG(IS_IOS) ||                                           \
546     (BUILDFLAG(IS_ANDROID) && BUILDFLAG(EXCLUDE_UNWIND_TABLES)) || \
547     (BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)) ||       \
548     (BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_CHROMEOS_DEVICE))
549 #define MAYBE_OtherLibrary DISABLED_OtherLibrary
550 #else
551 #define MAYBE_OtherLibrary OtherLibrary
552 #endif
553 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
554   ScopedNativeLibrary other_library(LoadOtherLibrary());
555   UnwindScenario scenario(
556       BindRepeating(&CallThroughOtherLibrary, Unretained(other_library.get())));
557   const std::vector<Frame>& sample = SampleScenario(&scenario, module_cache());
558
559   // The stack should contain a full unwind.
560   ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange(),
561                                scenario.GetSetupFunctionAddressRange(),
562                                scenario.GetOuterFunctionAddressRange()});
563 }
564
565 // Checks that a stack that runs through a library that is unloading produces a
566 // stack, and doesn't crash.
567 // Unloading is synchronous on the Mac, so this test is inapplicable.
568 // Android is not supported when EXCLUDE_UNWIND_TABLES |other_library| doesn't
569 // have unwind tables.
570 // TODO(https://crbug.com/1100175): Enable this test again for Android with
571 // ASAN. This is now disabled because the android-asan bot fails.
572 // If we're running the ChromeOS unit tests on Linux, this test will never pass
573 // because Ubuntu's libc isn't compiled with frame pointers. Skip if not a real
574 // ChromeOS device.
575 #if BUILDFLAG(IS_APPLE) ||                                         \
576     (BUILDFLAG(IS_ANDROID) && BUILDFLAG(EXCLUDE_UNWIND_TABLES)) || \
577     (BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)) ||       \
578     (BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_CHROMEOS_DEVICE))
579 #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary
580 #else
581 #define MAYBE_UnloadingLibrary UnloadingLibrary
582 #endif
583 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) {
584   TestLibraryUnload(false, module_cache());
585 }
586
587 // Checks that a stack that runs through a library that has been unloaded
588 // produces a stack, and doesn't crash.
589 // macOS ASAN is not yet supported - crbug.com/718628.
590 // Android is not supported since modules are found before unwinding.
591 // If we're running the ChromeOS unit tests on Linux, this test will never pass
592 // because Ubuntu's libc isn't compiled with frame pointers. Skip if not a real
593 // ChromeOS device.
594 #if (defined(ADDRESS_SANITIZER) && BUILDFLAG(IS_APPLE)) || \
595     BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) ||          \
596     (BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_CHROMEOS_DEVICE))
597 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
598 #else
599 #define MAYBE_UnloadedLibrary UnloadedLibrary
600 #endif
601 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
602   TestLibraryUnload(true, module_cache());
603 }
604
605 // Checks that a profiler can stop/destruct without ever having started.
606 PROFILER_TEST_F(StackSamplingProfilerTest, StopWithoutStarting) {
607   WithTargetThread(BindLambdaForTesting(
608       [this](SamplingProfilerThreadToken target_thread_token) {
609         SamplingParams params;
610         params.sampling_interval = Milliseconds(0);
611         params.samples_per_profile = 1;
612
613         Profile profile;
614         WaitableEvent sampling_completed(
615             WaitableEvent::ResetPolicy::MANUAL,
616             WaitableEvent::InitialState::NOT_SIGNALED);
617
618         StackSamplingProfiler profiler(
619             target_thread_token, params,
620             std::make_unique<TestProfileBuilder>(
621                 module_cache(),
622                 BindLambdaForTesting(
623                     [&profile, &sampling_completed](Profile result_profile) {
624                       profile = std::move(result_profile);
625                       sampling_completed.Signal();
626                     })),
627             CreateCoreUnwindersFactoryForTesting(module_cache()));
628
629         profiler.Stop();  // Constructed but never started.
630         EXPECT_FALSE(sampling_completed.IsSignaled());
631       }));
632 }
633
634 // Checks that its okay to stop a profiler before it finishes even when the
635 // sampling thread continues to run.
636 PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) {
637   // Test delegate that counts samples.
638   class SampleRecordedCounter : public StackSamplerTestDelegate {
639    public:
640     SampleRecordedCounter() = default;
641
642     void OnPreStackWalk() override {
643       AutoLock lock(lock_);
644       ++count_;
645     }
646
647     size_t Get() {
648       AutoLock lock(lock_);
649       return count_;
650     }
651
652    private:
653     Lock lock_;
654     size_t count_ = 0;
655   };
656
657   WithTargetThread(
658       BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) {
659         SamplingParams params[2];
660
661         // Providing an initial delay makes it more likely that both will be
662         // scheduled before either starts to run. Once started, samples will
663         // run ordered by their scheduled, interleaved times regardless of
664         // whatever interval the thread wakes up.
665         params[0].initial_delay = Milliseconds(10);
666         params[0].sampling_interval = Milliseconds(1);
667         params[0].samples_per_profile = 100000;
668
669         params[1].initial_delay = Milliseconds(10);
670         params[1].sampling_interval = Milliseconds(1);
671         params[1].samples_per_profile = 100000;
672
673         SampleRecordedCounter samples_recorded[std::size(params)];
674         ModuleCache module_cache1, module_cache2;
675         TestProfilerInfo profiler_info0(target_thread_token, params[0],
676                                         &module_cache1, &samples_recorded[0]);
677         TestProfilerInfo profiler_info1(target_thread_token, params[1],
678                                         &module_cache2, &samples_recorded[1]);
679
680         profiler_info0.profiler.Start();
681         profiler_info1.profiler.Start();
682
683         // Wait for both to start accumulating samples. Using a WaitableEvent is
684         // possible but gets complicated later on because there's no way of
685         // knowing if 0 or 1 additional sample will be taken after Stop() and
686         // thus no way of knowing how many Wait() calls to make on it.
687         while (samples_recorded[0].Get() == 0 || samples_recorded[1].Get() == 0)
688           PlatformThread::Sleep(Milliseconds(1));
689
690         // Ensure that the first sampler can be safely stopped while the second
691         // continues to run. The stopped first profiler will still have a
692         // RecordSampleTask pending that will do nothing when executed because
693         // the collection will have been removed by Stop().
694         profiler_info0.profiler.Stop();
695         profiler_info0.completed.Wait();
696         size_t count0 = samples_recorded[0].Get();
697         size_t count1 = samples_recorded[1].Get();
698
699         // Waiting for the second sampler to collect a couple samples ensures
700         // that the pending RecordSampleTask for the first has executed because
701         // tasks are always ordered by their next scheduled time.
702         while (samples_recorded[1].Get() < count1 + 2)
703           PlatformThread::Sleep(Milliseconds(1));
704
705         // Ensure that the first profiler didn't do anything since it was
706         // stopped.
707         EXPECT_EQ(count0, samples_recorded[0].Get());
708       }));
709 }
710
711 // Checks that no sample are captured if the profiling is stopped during the
712 // initial delay.
713 PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInitialDelay) {
714   SamplingParams params;
715   params.initial_delay = Seconds(60);
716
717   std::vector<std::vector<Frame>> samples =
718       CaptureSamples(params, Milliseconds(0), module_cache());
719
720   EXPECT_TRUE(samples.empty());
721 }
722
723 // Checks that tasks can be stopped before completion and incomplete samples are
724 // captured.
725 PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) {
726   // Test delegate that counts samples.
727   class SampleRecordedEvent : public StackSamplerTestDelegate {
728    public:
729     SampleRecordedEvent()
730         : sample_recorded_(WaitableEvent::ResetPolicy::MANUAL,
731                            WaitableEvent::InitialState::NOT_SIGNALED) {}
732
733     void OnPreStackWalk() override { sample_recorded_.Signal(); }
734
735     void WaitForSample() { sample_recorded_.Wait(); }
736
737    private:
738     WaitableEvent sample_recorded_;
739   };
740
741   WithTargetThread(BindLambdaForTesting(
742       [this](SamplingProfilerThreadToken target_thread_token) {
743         SamplingParams params;
744
745         params.sampling_interval = AVeryLongTimeDelta();
746         params.samples_per_profile = 2;
747
748         SampleRecordedEvent samples_recorded;
749         TestProfilerInfo profiler_info(target_thread_token, params,
750                                        module_cache(), &samples_recorded);
751
752         profiler_info.profiler.Start();
753
754         // Wait for profiler to start accumulating samples.
755         samples_recorded.WaitForSample();
756
757         // Ensure that it can stop safely.
758         profiler_info.profiler.Stop();
759         profiler_info.completed.Wait();
760
761         EXPECT_EQ(1u, profiler_info.profile.samples.size());
762       }));
763 }
764
765 PROFILER_TEST_F(StackSamplingProfilerTest, GetNextSampleTime_NormalExecution) {
766   const auto& GetNextSampleTime =
767       StackSamplingProfiler::TestPeer::GetNextSampleTime;
768
769   const TimeTicks scheduled_current_sample_time = TimeTicks::UnixEpoch();
770   const TimeDelta sampling_interval = Milliseconds(10);
771
772   // When executing the sample at exactly the scheduled time the next sample
773   // should be one interval later.
774   EXPECT_EQ(scheduled_current_sample_time + sampling_interval,
775             GetNextSampleTime(scheduled_current_sample_time, sampling_interval,
776                               scheduled_current_sample_time));
777
778   // When executing the sample less than half an interval after the scheduled
779   // time the next sample also should be one interval later.
780   EXPECT_EQ(scheduled_current_sample_time + sampling_interval,
781             GetNextSampleTime(
782                 scheduled_current_sample_time, sampling_interval,
783                 scheduled_current_sample_time + 0.4 * sampling_interval));
784
785   // When executing the sample less than half an interval before the scheduled
786   // time the next sample also should be one interval later. This is not
787   // expected to occur in practice since delayed tasks never run early.
788   EXPECT_EQ(scheduled_current_sample_time + sampling_interval,
789             GetNextSampleTime(
790                 scheduled_current_sample_time, sampling_interval,
791                 scheduled_current_sample_time - 0.4 * sampling_interval));
792 }
793
794 PROFILER_TEST_F(StackSamplingProfilerTest, GetNextSampleTime_DelayedExecution) {
795   const auto& GetNextSampleTime =
796       StackSamplingProfiler::TestPeer::GetNextSampleTime;
797
798   const TimeTicks scheduled_current_sample_time = TimeTicks::UnixEpoch();
799   const TimeDelta sampling_interval = Milliseconds(10);
800
801   // When executing the sample between 0.5 and 1.5 intervals after the scheduled
802   // time the next sample should be two intervals later.
803   EXPECT_EQ(scheduled_current_sample_time + 2 * sampling_interval,
804             GetNextSampleTime(
805                 scheduled_current_sample_time, sampling_interval,
806                 scheduled_current_sample_time + 0.6 * sampling_interval));
807   EXPECT_EQ(scheduled_current_sample_time + 2 * sampling_interval,
808             GetNextSampleTime(
809                 scheduled_current_sample_time, sampling_interval,
810                 scheduled_current_sample_time + 1.0 * sampling_interval));
811   EXPECT_EQ(scheduled_current_sample_time + 2 * sampling_interval,
812             GetNextSampleTime(
813                 scheduled_current_sample_time, sampling_interval,
814                 scheduled_current_sample_time + 1.4 * sampling_interval));
815
816   // Similarly when executing the sample between 9.5 and 10.5 intervals after
817   // the scheduled time the next sample should be 11 intervals later.
818   EXPECT_EQ(scheduled_current_sample_time + 11 * sampling_interval,
819             GetNextSampleTime(
820                 scheduled_current_sample_time, sampling_interval,
821                 scheduled_current_sample_time + 9.6 * sampling_interval));
822   EXPECT_EQ(scheduled_current_sample_time + 11 * sampling_interval,
823             GetNextSampleTime(
824                 scheduled_current_sample_time, sampling_interval,
825                 scheduled_current_sample_time + 10.0 * sampling_interval));
826   EXPECT_EQ(scheduled_current_sample_time + 11 * sampling_interval,
827             GetNextSampleTime(
828                 scheduled_current_sample_time, sampling_interval,
829                 scheduled_current_sample_time + 10.4 * sampling_interval));
830 }
831
832 // Checks that we can destroy the profiler while profiling.
833 PROFILER_TEST_F(StackSamplingProfilerTest, DestroyProfilerWhileProfiling) {
834   SamplingParams params;
835   params.sampling_interval = Milliseconds(10);
836
837   Profile profile;
838   WithTargetThread(BindLambdaForTesting([&, this](SamplingProfilerThreadToken
839                                                       target_thread_token) {
840     std::unique_ptr<StackSamplingProfiler> profiler;
841     auto profile_builder = std::make_unique<TestProfileBuilder>(
842         module_cache(),
843         BindLambdaForTesting([&profile](Profile result_profile) {
844           profile = std::move(result_profile);
845         }));
846     profiler = std::make_unique<StackSamplingProfiler>(
847         target_thread_token, params, std::move(profile_builder),
848         CreateCoreUnwindersFactoryForTesting(module_cache()));
849     profiler->Start();
850     profiler.reset();
851
852     // Wait longer than a sample interval to catch any use-after-free actions by
853     // the profiler thread.
854     PlatformThread::Sleep(Milliseconds(50));
855   }));
856 }
857
858 // Checks that the different profilers may be run.
859 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) {
860   SamplingParams params;
861   params.sampling_interval = Milliseconds(0);
862   params.samples_per_profile = 1;
863
864   std::vector<std::vector<Frame>> samples =
865       CaptureSamples(params, AVeryLongTimeDelta(), module_cache());
866   ASSERT_EQ(1u, samples.size());
867
868   samples = CaptureSamples(params, AVeryLongTimeDelta(), module_cache());
869   ASSERT_EQ(1u, samples.size());
870 }
871
872 // Checks that a sampler can be started while another is running.
873 PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) {
874   WithTargetThread(
875       BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) {
876         SamplingParams params1;
877         params1.initial_delay = AVeryLongTimeDelta();
878         params1.samples_per_profile = 1;
879         ModuleCache module_cache1;
880         TestProfilerInfo profiler_info1(target_thread_token, params1,
881                                         &module_cache1);
882
883         SamplingParams params2;
884         params2.sampling_interval = Milliseconds(1);
885         params2.samples_per_profile = 1;
886         ModuleCache module_cache2;
887         TestProfilerInfo profiler_info2(target_thread_token, params2,
888                                         &module_cache2);
889
890         profiler_info1.profiler.Start();
891         profiler_info2.profiler.Start();
892         profiler_info2.completed.Wait();
893         EXPECT_EQ(1u, profiler_info2.profile.samples.size());
894       }));
895 }
896
897 // Checks that the profile duration and the sampling interval are calculated
898 // correctly. Also checks that RecordMetadata() is invoked each time a sample
899 // is recorded.
900 PROFILER_TEST_F(StackSamplingProfilerTest, ProfileGeneralInfo) {
901   WithTargetThread(BindLambdaForTesting(
902       [this](SamplingProfilerThreadToken target_thread_token) {
903         SamplingParams params;
904         params.sampling_interval = Milliseconds(1);
905         params.samples_per_profile = 3;
906
907         TestProfilerInfo profiler_info(target_thread_token, params,
908                                        module_cache());
909
910         profiler_info.profiler.Start();
911         profiler_info.completed.Wait();
912         EXPECT_EQ(3u, profiler_info.profile.samples.size());
913
914         // The profile duration should be greater than the total sampling
915         // intervals.
916         EXPECT_GT(profiler_info.profile.profile_duration,
917                   profiler_info.profile.sampling_period * 3);
918
919         EXPECT_EQ(Milliseconds(1), profiler_info.profile.sampling_period);
920
921         // The number of invocations of RecordMetadata() should be equal to the
922         // number of samples recorded.
923         EXPECT_EQ(3, profiler_info.profile.record_metadata_count);
924       }));
925 }
926
927 // Checks that the sampling thread can shut down.
928 PROFILER_TEST_F(StackSamplingProfilerTest, SamplerIdleShutdown) {
929   SamplingParams params;
930   params.sampling_interval = Milliseconds(0);
931   params.samples_per_profile = 1;
932
933   std::vector<std::vector<Frame>> samples =
934       CaptureSamples(params, AVeryLongTimeDelta(), module_cache());
935   ASSERT_EQ(1u, samples.size());
936
937   // Capture thread should still be running at this point.
938   ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
939
940   // Initiate an "idle" shutdown and ensure it happens. Idle-shutdown was
941   // disabled by the test fixture so the test will fail due to a timeout if
942   // it does not exit.
943   StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false);
944
945   // While the shutdown has been initiated, the actual exit of the thread still
946   // happens asynchronously. Watch until the thread actually exits. This test
947   // will time-out in the case of failure.
948   while (StackSamplingProfiler::TestPeer::IsSamplingThreadRunning())
949     PlatformThread::Sleep(Milliseconds(1));
950 }
951
952 // Checks that additional requests will restart a stopped profiler.
953 PROFILER_TEST_F(StackSamplingProfilerTest,
954                 WillRestartSamplerAfterIdleShutdown) {
955   SamplingParams params;
956   params.sampling_interval = Milliseconds(0);
957   params.samples_per_profile = 1;
958
959   std::vector<std::vector<Frame>> samples =
960       CaptureSamples(params, AVeryLongTimeDelta(), module_cache());
961   ASSERT_EQ(1u, samples.size());
962
963   // Capture thread should still be running at this point.
964   ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
965
966   // Post a ShutdownTask on the sampling thread which, when executed, will
967   // mark the thread as EXITING and begin shut down of the thread.
968   StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false);
969
970   // Ensure another capture will start the sampling thread and run.
971   samples = CaptureSamples(params, AVeryLongTimeDelta(), module_cache());
972   ASSERT_EQ(1u, samples.size());
973   EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
974 }
975
976 // Checks that it's safe to stop a task after it's completed and the sampling
977 // thread has shut-down for being idle.
978 PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) {
979   WithTargetThread(BindLambdaForTesting(
980       [this](SamplingProfilerThreadToken target_thread_token) {
981         SamplingParams params;
982
983         params.sampling_interval = Milliseconds(1);
984         params.samples_per_profile = 1;
985
986         TestProfilerInfo profiler_info(target_thread_token, params,
987                                        module_cache());
988
989         profiler_info.profiler.Start();
990         profiler_info.completed.Wait();
991
992         // Capture thread should still be running at this point.
993         ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
994
995         // Perform an idle shutdown.
996         StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(
997             false);
998
999         // Stop should be safe though its impossible to know at this moment if
1000         // the sampling thread has completely exited or will just "stop soon".
1001         profiler_info.profiler.Stop();
1002       }));
1003 }
1004
1005 // Checks that profilers can run both before and after the sampling thread has
1006 // started.
1007 PROFILER_TEST_F(StackSamplingProfilerTest,
1008                 ProfileBeforeAndAfterSamplingThreadRunning) {
1009   WithTargetThread(
1010       BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) {
1011         ModuleCache module_cache1;
1012         ModuleCache module_cache2;
1013
1014         std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos;
1015         profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1016             target_thread_token,
1017             SamplingParams{/*initial_delay=*/AVeryLongTimeDelta(),
1018                            /*samples_per_profile=*/1,
1019                            /*sampling_interval=*/Milliseconds(1)},
1020             &module_cache1));
1021         profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1022             target_thread_token,
1023             SamplingParams{/*initial_delay=*/Milliseconds(0),
1024                            /*samples_per_profile=*/1,
1025                            /*sampling_interval=*/Milliseconds(1)},
1026             &module_cache2));
1027
1028         // First profiler is started when there has never been a sampling
1029         // thread.
1030         EXPECT_FALSE(
1031             StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
1032         profiler_infos[0]->profiler.Start();
1033         // Second profiler is started when sampling thread is already running.
1034         EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
1035         profiler_infos[1]->profiler.Start();
1036
1037         // Only the second profiler should finish before test times out.
1038         size_t completed_profiler = WaitForSamplingComplete(profiler_infos);
1039         EXPECT_EQ(1U, completed_profiler);
1040       }));
1041 }
1042
1043 // Checks that an idle-shutdown task will abort if a new profiler starts
1044 // between when it was posted and when it runs.
1045 PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) {
1046   WithTargetThread(BindLambdaForTesting(
1047       [this](SamplingProfilerThreadToken target_thread_token) {
1048         SamplingParams params;
1049
1050         params.sampling_interval = Milliseconds(1);
1051         params.samples_per_profile = 1;
1052
1053         TestProfilerInfo profiler_info(target_thread_token, params,
1054                                        module_cache());
1055
1056         profiler_info.profiler.Start();
1057         profiler_info.completed.Wait();
1058         EXPECT_EQ(1u, profiler_info.profile.samples.size());
1059
1060         // Perform an idle shutdown but simulate that a new capture is started
1061         // before it can actually run.
1062         StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(
1063             true);
1064
1065         // Though the shutdown-task has been executed, any actual exit of the
1066         // thread is asynchronous so there is no way to detect that *didn't*
1067         // exit except to wait a reasonable amount of time and then check. Since
1068         // the thread was just running ("perform" blocked until it was), it
1069         // should finish almost immediately and without any waiting for tasks or
1070         // events.
1071         PlatformThread::Sleep(Milliseconds(200));
1072         EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
1073
1074         // Ensure that it's still possible to run another sampler.
1075         TestProfilerInfo another_info(target_thread_token, params,
1076                                       module_cache());
1077         another_info.profiler.Start();
1078         another_info.completed.Wait();
1079         EXPECT_EQ(1u, another_info.profile.samples.size());
1080       }));
1081 }
1082
1083 // Checks that synchronized multiple sampling requests execute in parallel.
1084 PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) {
1085   WithTargetThread(
1086       BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) {
1087         std::vector<ModuleCache> module_caches(2);
1088
1089         // Providing an initial delay makes it more likely that both will be
1090         // scheduled before either starts to run. Once started, samples will
1091         // run ordered by their scheduled, interleaved times regardless of
1092         // whatever interval the thread wakes up. Thus, total execution time
1093         // will be 10ms (delay) + 10x1ms (sampling) + 1/2 timer minimum
1094         // interval.
1095         std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos;
1096         profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1097             target_thread_token,
1098             SamplingParams{/*initial_delay=*/Milliseconds(10),
1099                            /*samples_per_profile=*/9,
1100                            /*sampling_interval=*/Milliseconds(1)},
1101             &module_caches[0]));
1102         profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1103             target_thread_token,
1104             SamplingParams{/*initial_delay=*/Milliseconds(11),
1105                            /*samples_per_profile=*/8,
1106                            /*sampling_interval=*/Milliseconds(1)},
1107             &module_caches[1]));
1108
1109         profiler_infos[0]->profiler.Start();
1110         profiler_infos[1]->profiler.Start();
1111
1112         // Wait for one profiler to finish.
1113         size_t completed_profiler = WaitForSamplingComplete(profiler_infos);
1114
1115         size_t other_profiler = 1 - completed_profiler;
1116         // Wait for the other profiler to finish.
1117         profiler_infos[other_profiler]->completed.Wait();
1118
1119         // Ensure each got the correct number of samples.
1120         EXPECT_EQ(9u, profiler_infos[0]->profile.samples.size());
1121         EXPECT_EQ(8u, profiler_infos[1]->profile.samples.size());
1122       }));
1123 }
1124
1125 // Checks that several mixed sampling requests execute in parallel.
1126 PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) {
1127   WithTargetThread(BindLambdaForTesting([](SamplingProfilerThreadToken
1128                                                target_thread_token) {
1129     std::vector<ModuleCache> module_caches(3);
1130
1131     std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos;
1132     profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1133         target_thread_token,
1134         SamplingParams{/*initial_delay=*/Milliseconds(8),
1135                        /*samples_per_profile=*/10,
1136                        /*sampling_interval=*/Milliseconds(4)},
1137         &module_caches[0]));
1138     profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1139         target_thread_token,
1140         SamplingParams{/*initial_delay=*/Milliseconds(9),
1141                        /*samples_per_profile=*/10,
1142                        /*sampling_interval=*/Milliseconds(3)},
1143         &module_caches[1]));
1144     profiler_infos.push_back(std::make_unique<TestProfilerInfo>(
1145         target_thread_token,
1146         SamplingParams{/*initial_delay=*/Milliseconds(10),
1147                        /*samples_per_profile=*/10,
1148                        /*sampling_interval=*/Milliseconds(2)},
1149         &module_caches[2]));
1150
1151     for (auto& i : profiler_infos)
1152       i->profiler.Start();
1153
1154     // Wait for one profiler to finish.
1155     size_t completed_profiler = WaitForSamplingComplete(profiler_infos);
1156     EXPECT_EQ(10u, profiler_infos[completed_profiler]->profile.samples.size());
1157     // Stop and destroy all profilers, always in the same order. Don't
1158     // crash.
1159     for (auto& i : profiler_infos)
1160       i->profiler.Stop();
1161     for (auto& i : profiler_infos)
1162       i.reset();
1163   }));
1164 }
1165
1166 // Checks that different threads can be sampled in parallel.
1167 PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) {
1168   UnwindScenario scenario1(BindRepeating(&CallWithPlainFunction));
1169   UnwindScenario::SampleEvents events1;
1170   TargetThread target_thread1(
1171       BindLambdaForTesting([&]() { scenario1.Execute(&events1); }));
1172   target_thread1.Start();
1173   events1.ready_for_sample.Wait();
1174
1175   UnwindScenario scenario2(BindRepeating(&CallWithPlainFunction));
1176   UnwindScenario::SampleEvents events2;
1177   TargetThread target_thread2(
1178       BindLambdaForTesting([&]() { scenario2.Execute(&events2); }));
1179   target_thread2.Start();
1180   events2.ready_for_sample.Wait();
1181
1182   // Providing an initial delay makes it more likely that both will be
1183   // scheduled before either starts to run. Once started, samples will
1184   // run ordered by their scheduled, interleaved times regardless of
1185   // whatever interval the thread wakes up.
1186   SamplingParams params1, params2;
1187   params1.initial_delay = Milliseconds(10);
1188   params1.sampling_interval = Milliseconds(1);
1189   params1.samples_per_profile = 9;
1190   params2.initial_delay = Milliseconds(10);
1191   params2.sampling_interval = Milliseconds(1);
1192   params2.samples_per_profile = 8;
1193
1194   Profile profile1, profile2;
1195   ModuleCache module_cache1, module_cache2;
1196
1197   WaitableEvent sampling_thread_completed1(
1198       WaitableEvent::ResetPolicy::MANUAL,
1199       WaitableEvent::InitialState::NOT_SIGNALED);
1200   StackSamplingProfiler profiler1(
1201       target_thread1.thread_token(), params1,
1202       std::make_unique<TestProfileBuilder>(
1203           &module_cache1,
1204           BindLambdaForTesting(
1205               [&profile1, &sampling_thread_completed1](Profile result_profile) {
1206                 profile1 = std::move(result_profile);
1207                 sampling_thread_completed1.Signal();
1208               })),
1209       CreateCoreUnwindersFactoryForTesting(&module_cache1));
1210
1211   WaitableEvent sampling_thread_completed2(
1212       WaitableEvent::ResetPolicy::MANUAL,
1213       WaitableEvent::InitialState::NOT_SIGNALED);
1214   StackSamplingProfiler profiler2(
1215       target_thread2.thread_token(), params2,
1216       std::make_unique<TestProfileBuilder>(
1217           &module_cache2,
1218           BindLambdaForTesting(
1219               [&profile2, &sampling_thread_completed2](Profile result_profile) {
1220                 profile2 = std::move(result_profile);
1221                 sampling_thread_completed2.Signal();
1222               })),
1223       CreateCoreUnwindersFactoryForTesting(&module_cache2));
1224
1225   // Finally the real work.
1226   profiler1.Start();
1227   profiler2.Start();
1228   sampling_thread_completed1.Wait();
1229   sampling_thread_completed2.Wait();
1230   EXPECT_EQ(9u, profile1.samples.size());
1231   EXPECT_EQ(8u, profile2.samples.size());
1232
1233   events1.sample_finished.Signal();
1234   events2.sample_finished.Signal();
1235   target_thread1.Join();
1236   target_thread2.Join();
1237 }
1238
1239 // A simple thread that runs a profiler on another thread.
1240 class ProfilerThread : public SimpleThread {
1241  public:
1242   ProfilerThread(const std::string& name,
1243                  SamplingProfilerThreadToken thread_token,
1244                  const SamplingParams& params,
1245                  ModuleCache* module_cache)
1246       : SimpleThread(name, Options()),
1247         run_(WaitableEvent::ResetPolicy::MANUAL,
1248              WaitableEvent::InitialState::NOT_SIGNALED),
1249         completed_(WaitableEvent::ResetPolicy::MANUAL,
1250                    WaitableEvent::InitialState::NOT_SIGNALED),
1251         profiler_(thread_token,
1252                   params,
1253                   std::make_unique<TestProfileBuilder>(
1254                       module_cache,
1255                       BindLambdaForTesting([this](Profile result_profile) {
1256                         profile_ = std::move(result_profile);
1257                         completed_.Signal();
1258                       })),
1259                   CreateCoreUnwindersFactoryForTesting(module_cache)) {}
1260   void Run() override {
1261     run_.Wait();
1262     profiler_.Start();
1263   }
1264
1265   void Go() { run_.Signal(); }
1266
1267   void Wait() { completed_.Wait(); }
1268
1269   Profile& profile() { return profile_; }
1270
1271  private:
1272   WaitableEvent run_;
1273
1274   Profile profile_;
1275   WaitableEvent completed_;
1276   StackSamplingProfiler profiler_;
1277 };
1278
1279 // Checks that different threads can run samplers in parallel.
1280 PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) {
1281   WithTargetThread(
1282       BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) {
1283         // Providing an initial delay makes it more likely that both will be
1284         // scheduled before either starts to run. Once started, samples will
1285         // run ordered by their scheduled, interleaved times regardless of
1286         // whatever interval the thread wakes up.
1287         SamplingParams params1, params2;
1288         params1.initial_delay = Milliseconds(10);
1289         params1.sampling_interval = Milliseconds(1);
1290         params1.samples_per_profile = 9;
1291         params2.initial_delay = Milliseconds(10);
1292         params2.sampling_interval = Milliseconds(1);
1293         params2.samples_per_profile = 8;
1294
1295         // Start the profiler threads and give them a moment to get going.
1296         ModuleCache module_cache1;
1297         ProfilerThread profiler_thread1("profiler1", target_thread_token,
1298                                         params1, &module_cache1);
1299         ModuleCache module_cache2;
1300         ProfilerThread profiler_thread2("profiler2", target_thread_token,
1301                                         params2, &module_cache2);
1302         profiler_thread1.Start();
1303         profiler_thread2.Start();
1304         PlatformThread::Sleep(Milliseconds(10));
1305
1306         // This will (approximately) synchronize the two threads.
1307         profiler_thread1.Go();
1308         profiler_thread2.Go();
1309
1310         // Wait for them both to finish and validate collection.
1311         profiler_thread1.Wait();
1312         profiler_thread2.Wait();
1313         EXPECT_EQ(9u, profiler_thread1.profile().samples.size());
1314         EXPECT_EQ(8u, profiler_thread2.profile().samples.size());
1315
1316         profiler_thread1.Join();
1317         profiler_thread2.Join();
1318       }));
1319 }
1320
1321 PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_BeforeStart) {
1322   SamplingParams params;
1323   params.sampling_interval = Milliseconds(0);
1324   params.samples_per_profile = 1;
1325
1326   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
1327
1328   int add_initial_modules_invocation_count = 0;
1329   const auto add_initial_modules_callback =
1330       [&add_initial_modules_invocation_count]() {
1331         ++add_initial_modules_invocation_count;
1332       };
1333
1334   Profile profile;
1335   WithTargetThread(
1336       &scenario,
1337       BindLambdaForTesting(
1338           [&](SamplingProfilerThreadToken target_thread_token) {
1339             WaitableEvent sampling_thread_completed(
1340                 WaitableEvent::ResetPolicy::MANUAL,
1341                 WaitableEvent::InitialState::NOT_SIGNALED);
1342             StackSamplingProfiler profiler(
1343                 target_thread_token, params,
1344                 std::make_unique<TestProfileBuilder>(
1345                     module_cache(),
1346                     BindLambdaForTesting([&profile, &sampling_thread_completed](
1347                                              Profile result_profile) {
1348                       profile = std::move(result_profile);
1349                       sampling_thread_completed.Signal();
1350                     })),
1351                 CreateCoreUnwindersFactoryForTesting(module_cache()));
1352             profiler.AddAuxUnwinder(std::make_unique<TestAuxUnwinder>(
1353                 Frame(23, nullptr),
1354                 BindLambdaForTesting(add_initial_modules_callback)));
1355             profiler.Start();
1356             sampling_thread_completed.Wait();
1357           }));
1358
1359   ASSERT_EQ(1, add_initial_modules_invocation_count);
1360
1361   // The sample should have one frame from the context values and one from the
1362   // TestAuxUnwinder.
1363   ASSERT_EQ(1u, profile.samples.size());
1364   const std::vector<Frame>& frames = profile.samples[0];
1365
1366   ASSERT_EQ(2u, frames.size());
1367   EXPECT_EQ(23u, frames[1].instruction_pointer);
1368   EXPECT_EQ(nullptr, frames[1].module);
1369 }
1370
1371 PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_AfterStart) {
1372   SamplingParams params;
1373   params.sampling_interval = Milliseconds(10);
1374   params.samples_per_profile = 2;
1375
1376   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
1377
1378   int add_initial_modules_invocation_count = 0;
1379   const auto add_initial_modules_callback =
1380       [&add_initial_modules_invocation_count]() {
1381         ++add_initial_modules_invocation_count;
1382       };
1383
1384   Profile profile;
1385   WithTargetThread(
1386       &scenario,
1387       BindLambdaForTesting(
1388           [&](SamplingProfilerThreadToken target_thread_token) {
1389             WaitableEvent sampling_thread_completed(
1390                 WaitableEvent::ResetPolicy::MANUAL,
1391                 WaitableEvent::InitialState::NOT_SIGNALED);
1392             StackSamplingProfiler profiler(
1393                 target_thread_token, params,
1394                 std::make_unique<TestProfileBuilder>(
1395                     module_cache(),
1396                     BindLambdaForTesting([&profile, &sampling_thread_completed](
1397                                              Profile result_profile) {
1398                       profile = std::move(result_profile);
1399                       sampling_thread_completed.Signal();
1400                     })),
1401                 CreateCoreUnwindersFactoryForTesting(module_cache()));
1402             profiler.Start();
1403             profiler.AddAuxUnwinder(std::make_unique<TestAuxUnwinder>(
1404                 Frame(23, nullptr),
1405                 BindLambdaForTesting(add_initial_modules_callback)));
1406             sampling_thread_completed.Wait();
1407           }));
1408
1409   ASSERT_EQ(1, add_initial_modules_invocation_count);
1410
1411   // The sample should have one frame from the context values and one from the
1412   // TestAuxUnwinder.
1413   ASSERT_EQ(2u, profile.samples.size());
1414
1415   // Whether the aux unwinder is available for the first sample is racy, so rely
1416   // on the second sample.
1417   const std::vector<Frame>& frames = profile.samples[1];
1418   ASSERT_EQ(2u, frames.size());
1419   EXPECT_EQ(23u, frames[1].instruction_pointer);
1420   EXPECT_EQ(nullptr, frames[1].module);
1421 }
1422
1423 PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_AfterStop) {
1424   SamplingParams params;
1425   params.sampling_interval = Milliseconds(0);
1426   params.samples_per_profile = 1;
1427
1428   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
1429
1430   Profile profile;
1431   WithTargetThread(
1432       &scenario,
1433       BindLambdaForTesting(
1434           [&](SamplingProfilerThreadToken target_thread_token) {
1435             WaitableEvent sampling_thread_completed(
1436                 WaitableEvent::ResetPolicy::MANUAL,
1437                 WaitableEvent::InitialState::NOT_SIGNALED);
1438             StackSamplingProfiler profiler(
1439                 target_thread_token, params,
1440                 std::make_unique<TestProfileBuilder>(
1441                     module_cache(),
1442                     BindLambdaForTesting([&profile, &sampling_thread_completed](
1443                                              Profile result_profile) {
1444                       profile = std::move(result_profile);
1445                       sampling_thread_completed.Signal();
1446                     })),
1447                 CreateCoreUnwindersFactoryForTesting(module_cache()));
1448             profiler.Start();
1449             profiler.Stop();
1450             profiler.AddAuxUnwinder(std::make_unique<TestAuxUnwinder>(
1451                 Frame(23, nullptr), base::RepeatingClosure()));
1452             sampling_thread_completed.Wait();
1453           }));
1454
1455   // The AuxUnwinder should be accepted without error. It will have no effect
1456   // since the collection has stopped.
1457 }
1458
1459 // Checks that requests to apply metadata to past samples are passed on to the
1460 // profile builder.
1461 PROFILER_TEST_F(StackSamplingProfilerTest,
1462                 ApplyMetadataToPastSamples_PassedToProfileBuilder) {
1463   // Runs the passed closure on the profiler thread after a sample is taken.
1464   class PostSampleInvoker : public StackSamplerTestDelegate {
1465    public:
1466     explicit PostSampleInvoker(RepeatingClosure post_sample_closure)
1467         : post_sample_closure_(std::move(post_sample_closure)) {}
1468
1469     void OnPreStackWalk() override { post_sample_closure_.Run(); }
1470
1471    private:
1472     RepeatingClosure post_sample_closure_;
1473   };
1474
1475   // Thread-safe representation of the times that samples were taken.
1476   class SynchronizedSampleTimes {
1477    public:
1478     void AddNow() {
1479       AutoLock lock(lock_);
1480       times_.push_back(TimeTicks::Now());
1481     }
1482
1483     std::vector<TimeTicks> GetTimes() {
1484       AutoLock lock(lock_);
1485       return times_;
1486     }
1487
1488    private:
1489     Lock lock_;
1490     std::vector<TimeTicks> times_;
1491   };
1492
1493   SamplingParams params;
1494   params.sampling_interval = Milliseconds(10);
1495   // 10,000 samples ensures the profiler continues running until manually
1496   // stopped, after applying metadata.
1497   params.samples_per_profile = 10000;
1498
1499   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
1500
1501   std::vector<TimeTicks> sample_times;
1502   Profile profile;
1503   WithTargetThread(
1504       &scenario,
1505       BindLambdaForTesting(
1506           [&](SamplingProfilerThreadToken target_thread_token) {
1507             SynchronizedSampleTimes synchronized_sample_times;
1508             WaitableEvent sample_seen(WaitableEvent::ResetPolicy::AUTOMATIC);
1509             PostSampleInvoker post_sample_invoker(BindLambdaForTesting([&]() {
1510               synchronized_sample_times.AddNow();
1511               sample_seen.Signal();
1512             }));
1513
1514             StackSamplingProfiler profiler(
1515                 target_thread_token, params,
1516                 std::make_unique<TestProfileBuilder>(
1517                     module_cache(),
1518                     BindLambdaForTesting([&profile](Profile result_profile) {
1519                       profile = std::move(result_profile);
1520                     })),
1521                 CreateCoreUnwindersFactoryForTesting(module_cache()),
1522                 RepeatingClosure(), &post_sample_invoker);
1523             profiler.Start();
1524             // Wait for 5 samples to be collected.
1525             for (int i = 0; i < 5; ++i)
1526               sample_seen.Wait();
1527             sample_times = synchronized_sample_times.GetTimes();
1528             // Record metadata on past samples, with and without a key value.
1529             // The range [times[1], times[3]] is guaranteed to include only
1530             // samples 2 and 3, and likewise [times[2], times[4]] is guaranteed
1531             // to include only samples 3 and 4.
1532             ApplyMetadataToPastSamples(sample_times[1], sample_times[3],
1533                                        "TestMetadata1", 10,
1534                                        base::SampleMetadataScope::kProcess);
1535             ApplyMetadataToPastSamples(sample_times[2], sample_times[4],
1536                                        "TestMetadata2", 100, 11,
1537                                        base::SampleMetadataScope::kProcess);
1538             profiler.Stop();
1539           }));
1540
1541   ASSERT_EQ(2u, profile.retrospective_metadata.size());
1542
1543   const RetrospectiveMetadata& metadata1 = profile.retrospective_metadata[0];
1544   EXPECT_EQ(sample_times[1], metadata1.period_start);
1545   EXPECT_EQ(sample_times[3], metadata1.period_end);
1546   EXPECT_EQ(HashMetricName("TestMetadata1"), metadata1.item.name_hash);
1547   EXPECT_FALSE(metadata1.item.key.has_value());
1548   EXPECT_EQ(10, metadata1.item.value);
1549
1550   const RetrospectiveMetadata& metadata2 = profile.retrospective_metadata[1];
1551   EXPECT_EQ(sample_times[2], metadata2.period_start);
1552   EXPECT_EQ(sample_times[4], metadata2.period_end);
1553   EXPECT_EQ(HashMetricName("TestMetadata2"), metadata2.item.name_hash);
1554   ASSERT_TRUE(metadata2.item.key.has_value());
1555   EXPECT_EQ(100, *metadata2.item.key);
1556   EXPECT_EQ(11, metadata2.item.value);
1557 }
1558
1559 PROFILER_TEST_F(
1560     StackSamplingProfilerTest,
1561     ApplyMetadataToPastSamples_PassedToProfileBuilder_MultipleCollections) {
1562   SamplingParams params;
1563   params.sampling_interval = Milliseconds(10);
1564   // 10,000 samples ensures the profiler continues running until manually
1565   // stopped, after applying metadata.
1566   params.samples_per_profile = 10000;
1567   ModuleCache module_cache1, module_cache2;
1568
1569   WaitableEvent profiler1_started;
1570   WaitableEvent profiler2_started;
1571   WaitableEvent profiler1_metadata_applied;
1572   WaitableEvent profiler2_metadata_applied;
1573
1574   Profile profile1;
1575   WaitableEvent sampling_completed1;
1576   TargetThread target_thread1(BindLambdaForTesting([&]() {
1577     StackSamplingProfiler profiler1(
1578         target_thread1.thread_token(), params,
1579         std::make_unique<TestProfileBuilder>(
1580             &module_cache1, BindLambdaForTesting([&](Profile result_profile) {
1581               profile1 = std::move(result_profile);
1582               sampling_completed1.Signal();
1583             })),
1584         CreateCoreUnwindersFactoryForTesting(&module_cache1),
1585         RepeatingClosure());
1586     profiler1.Start();
1587     profiler1_started.Signal();
1588     profiler2_started.Wait();
1589
1590     // Record metadata on past samples only for this thread. The time range
1591     // shouldn't affect the outcome, it should always be passed to the
1592     // ProfileBuilder.
1593     ApplyMetadataToPastSamples(TimeTicks(), TimeTicks::Now(), "TestMetadata1",
1594                                10, 10, SampleMetadataScope::kThread);
1595
1596     profiler1_metadata_applied.Signal();
1597     profiler2_metadata_applied.Wait();
1598     profiler1.Stop();
1599   }));
1600   target_thread1.Start();
1601
1602   Profile profile2;
1603   WaitableEvent sampling_completed2;
1604   TargetThread target_thread2(BindLambdaForTesting([&]() {
1605     StackSamplingProfiler profiler2(
1606         target_thread2.thread_token(), params,
1607         std::make_unique<TestProfileBuilder>(
1608             &module_cache2, BindLambdaForTesting([&](Profile result_profile) {
1609               profile2 = std::move(result_profile);
1610               sampling_completed2.Signal();
1611             })),
1612         CreateCoreUnwindersFactoryForTesting(&module_cache2),
1613         RepeatingClosure());
1614     profiler2.Start();
1615     profiler2_started.Signal();
1616     profiler1_started.Wait();
1617
1618     // Record metadata on past samples only for this thread.
1619     ApplyMetadataToPastSamples(TimeTicks(), TimeTicks::Now(), "TestMetadata2",
1620                                20, 20, SampleMetadataScope::kThread);
1621
1622     profiler2_metadata_applied.Signal();
1623     profiler1_metadata_applied.Wait();
1624     profiler2.Stop();
1625   }));
1626   target_thread2.Start();
1627
1628   target_thread1.Join();
1629   target_thread2.Join();
1630
1631   // Wait for the profile to be captured before checking expectations.
1632   sampling_completed1.Wait();
1633   sampling_completed2.Wait();
1634
1635   ASSERT_EQ(1u, profile1.retrospective_metadata.size());
1636   ASSERT_EQ(1u, profile2.retrospective_metadata.size());
1637
1638   {
1639     const RetrospectiveMetadata& metadata1 = profile1.retrospective_metadata[0];
1640     EXPECT_EQ(HashMetricName("TestMetadata1"), metadata1.item.name_hash);
1641     ASSERT_TRUE(metadata1.item.key.has_value());
1642     EXPECT_EQ(10, *metadata1.item.key);
1643     EXPECT_EQ(10, metadata1.item.value);
1644   }
1645   {
1646     const RetrospectiveMetadata& metadata2 = profile2.retrospective_metadata[0];
1647     EXPECT_EQ(HashMetricName("TestMetadata2"), metadata2.item.name_hash);
1648     ASSERT_TRUE(metadata2.item.key.has_value());
1649     EXPECT_EQ(20, *metadata2.item.key);
1650     EXPECT_EQ(20, metadata2.item.value);
1651   }
1652 }
1653
1654 // Checks that requests to add profile metadata are passed on to the profile
1655 // builder.
1656 PROFILER_TEST_F(StackSamplingProfilerTest,
1657                 AddProfileMetadata_PassedToProfileBuilder) {
1658   // Runs the passed closure on the profiler thread after a sample is taken.
1659   class PostSampleInvoker : public StackSamplerTestDelegate {
1660    public:
1661     explicit PostSampleInvoker(RepeatingClosure post_sample_closure)
1662         : post_sample_closure_(std::move(post_sample_closure)) {}
1663
1664     void OnPreStackWalk() override { post_sample_closure_.Run(); }
1665
1666    private:
1667     RepeatingClosure post_sample_closure_;
1668   };
1669
1670   SamplingParams params;
1671   params.sampling_interval = Milliseconds(10);
1672   // 10,000 samples ensures the profiler continues running until manually
1673   // stopped.
1674   params.samples_per_profile = 10000;
1675
1676   UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
1677
1678   Profile profile;
1679   WithTargetThread(
1680       &scenario,
1681       BindLambdaForTesting(
1682           [&](SamplingProfilerThreadToken target_thread_token) {
1683             WaitableEvent sample_seen(WaitableEvent::ResetPolicy::AUTOMATIC);
1684             PostSampleInvoker post_sample_invoker(
1685                 BindLambdaForTesting([&]() { sample_seen.Signal(); }));
1686
1687             StackSamplingProfiler profiler(
1688                 target_thread_token, params,
1689                 std::make_unique<TestProfileBuilder>(
1690                     module_cache(),
1691                     BindLambdaForTesting([&profile](Profile result_profile) {
1692                       profile = std::move(result_profile);
1693                     })),
1694                 CreateCoreUnwindersFactoryForTesting(module_cache()),
1695                 RepeatingClosure(), &post_sample_invoker);
1696             profiler.Start();
1697             sample_seen.Wait();
1698             AddProfileMetadata("TestMetadata", 1, 2,
1699                                SampleMetadataScope::kProcess);
1700             profiler.Stop();
1701           }));
1702
1703   ASSERT_EQ(1u, profile.profile_metadata.size());
1704   const MetadataRecorder::Item& item = profile.profile_metadata[0];
1705   EXPECT_EQ(HashMetricName("TestMetadata"), item.name_hash);
1706   EXPECT_EQ(1, *item.key);
1707   EXPECT_EQ(2, item.value);
1708 }
1709
1710 PROFILER_TEST_F(StackSamplingProfilerTest,
1711                 AddProfileMetadata_PassedToProfileBuilder_MultipleCollections) {
1712   SamplingParams params;
1713   params.sampling_interval = Milliseconds(10);
1714   // 10,000 samples ensures the profiler continues running until manually
1715   // stopped.
1716   params.samples_per_profile = 10000;
1717   ModuleCache module_cache1, module_cache2;
1718
1719   WaitableEvent profiler1_started;
1720   WaitableEvent profiler2_started;
1721   WaitableEvent profiler1_metadata_applied;
1722   WaitableEvent profiler2_metadata_applied;
1723
1724   Profile profile1;
1725   WaitableEvent sampling_completed1;
1726   TargetThread target_thread1(BindLambdaForTesting([&]() {
1727     StackSamplingProfiler profiler1(
1728         target_thread1.thread_token(), params,
1729         std::make_unique<TestProfileBuilder>(
1730             &module_cache1, BindLambdaForTesting([&](Profile result_profile) {
1731               profile1 = std::move(result_profile);
1732               sampling_completed1.Signal();
1733             })),
1734         CreateCoreUnwindersFactoryForTesting(&module_cache1),
1735         RepeatingClosure());
1736     profiler1.Start();
1737     profiler1_started.Signal();
1738     profiler2_started.Wait();
1739
1740     AddProfileMetadata("TestMetadata1", 1, 2, SampleMetadataScope::kThread);
1741
1742     profiler1_metadata_applied.Signal();
1743     profiler2_metadata_applied.Wait();
1744     profiler1.Stop();
1745   }));
1746   target_thread1.Start();
1747
1748   Profile profile2;
1749   WaitableEvent sampling_completed2;
1750   TargetThread target_thread2(BindLambdaForTesting([&]() {
1751     StackSamplingProfiler profiler2(
1752         target_thread2.thread_token(), params,
1753         std::make_unique<TestProfileBuilder>(
1754             &module_cache2, BindLambdaForTesting([&](Profile result_profile) {
1755               profile2 = std::move(result_profile);
1756               sampling_completed2.Signal();
1757             })),
1758         CreateCoreUnwindersFactoryForTesting(&module_cache2),
1759         RepeatingClosure());
1760     profiler2.Start();
1761     profiler2_started.Signal();
1762     profiler1_started.Wait();
1763
1764     AddProfileMetadata("TestMetadata2", 11, 12, SampleMetadataScope::kThread);
1765
1766     profiler2_metadata_applied.Signal();
1767     profiler1_metadata_applied.Wait();
1768     profiler2.Stop();
1769   }));
1770   target_thread2.Start();
1771
1772   target_thread1.Join();
1773   target_thread2.Join();
1774
1775   // Wait for the profile to be captured before checking expectations.
1776   sampling_completed1.Wait();
1777   sampling_completed2.Wait();
1778
1779   ASSERT_EQ(1u, profile1.profile_metadata.size());
1780   ASSERT_EQ(1u, profile2.profile_metadata.size());
1781
1782   {
1783     const MetadataRecorder::Item& item = profile1.profile_metadata[0];
1784     EXPECT_EQ(HashMetricName("TestMetadata1"), item.name_hash);
1785     ASSERT_TRUE(item.key.has_value());
1786     EXPECT_EQ(1, *item.key);
1787     EXPECT_EQ(2, item.value);
1788   }
1789   {
1790     const MetadataRecorder::Item& item = profile2.profile_metadata[0];
1791     EXPECT_EQ(HashMetricName("TestMetadata2"), item.name_hash);
1792     ASSERT_TRUE(item.key.has_value());
1793     EXPECT_EQ(11, *item.key);
1794     EXPECT_EQ(12, item.value);
1795   }
1796 }
1797
1798 }  // namespace base