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)27StackUnwindData::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()34std::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)44void 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()61void 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)66void 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