• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 "base/profiler/stack_unwind_data.h"
6 
7 #include <iterator>
8 #include <utility>
9 
10 #include "base/check.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/metrics/histogram_functions.h"
15 #include "base/numerics/safe_conversions.h"
16 #include "base/profiler/metadata_recorder.h"
17 #include "base/profiler/profile_builder.h"
18 #include "base/profiler/sample_metadata.h"
19 #include "base/profiler/stack_buffer.h"
20 #include "base/profiler/stack_copier.h"
21 #include "base/profiler/suspendable_thread_delegate.h"
22 #include "base/profiler/unwinder.h"
23 #include "base/ranges/algorithm.h"
24 
25 namespace base {
26 
StackUnwindData(std::unique_ptr<ProfileBuilder> profile_builder)27 StackUnwindData::StackUnwindData(
28     std::unique_ptr<ProfileBuilder> profile_builder)
29     : profile_builder_(std::move(profile_builder)),
30       module_cache_(profile_builder_->GetModuleCache()) {}
31 
32 StackUnwindData::~StackUnwindData() = default;
33 
GetUnwinderSnapshot()34 std::vector<UnwinderCapture> StackUnwindData::GetUnwinderSnapshot() {
35   DCHECK_CALLED_ON_VALID_SEQUENCE(sampling_thread_sequence_checker_);
36   std::vector<UnwinderCapture> unwinders;
37   for (const auto& unwinder : unwinders_) {
38     unwinders.emplace_back(unwinder.get(),
39                            unwinder->CreateUnwinderStateCapture());
40   }
41   return unwinders;
42 }
43 
Initialize(std::vector<std::unique_ptr<Unwinder>> unwinders)44 void StackUnwindData::Initialize(
45     std::vector<std::unique_ptr<Unwinder>> unwinders) {
46   DETACH_FROM_SEQUENCE(sampling_thread_sequence_checker_);
47   DETACH_FROM_SEQUENCE(worker_sequence_checker_);
48   DCHECK_CALLED_ON_VALID_SEQUENCE(sampling_thread_sequence_checker_);
49   // |unwinders| is iterated backward since |unwinders_factory_| generates
50   // unwinders in increasing priority order. |unwinders_| is stored in
51   // decreasing priority order for ease of use within the class.
52   unwinders_.insert(unwinders_.end(),
53                     std::make_move_iterator(unwinders.rbegin()),
54                     std::make_move_iterator(unwinders.rend()));
55 
56   for (const auto& unwinder : unwinders_) {
57     unwinder->Initialize(module_cache_);
58   }
59 }
60 
OnThreadPoolRunning()61 void StackUnwindData::OnThreadPoolRunning() {
62   DCHECK_CALLED_ON_VALID_SEQUENCE(sampling_thread_sequence_checker_);
63   DETACH_FROM_SEQUENCE(worker_sequence_checker_);
64 }
65 
AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder)66 void StackUnwindData::AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder) {
67   DCHECK_CALLED_ON_VALID_SEQUENCE(sampling_thread_sequence_checker_);
68   // Unwinder would already be initialized on the SamplingThread.
69   unwinders_.push_front(std::move(unwinder));
70 }
71 
72 }  // namespace base
73