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 #ifndef BASE_PROFILER_STACK_UNWIND_DATA_H_ 6 #define BASE_PROFILER_STACK_UNWIND_DATA_H_ 7 8 #include <memory> 9 #include <tuple> 10 #include <vector> 11 12 #include "base/base_export.h" 13 #include "base/containers/circular_deque.h" 14 #include "base/memory/raw_ptr.h" 15 #include "base/profiler/frame.h" 16 #include "base/profiler/register_context.h" 17 #include "base/sequence_checker.h" 18 #include "base/synchronization/lock.h" 19 #include "base/task/sequenced_task_runner.h" 20 #include "base/thread_annotations.h" 21 22 namespace base { 23 24 class ProfileBuilder; 25 class Unwinder; 26 class ModuleCache; 27 class UnwinderStateCapture; 28 29 using UnwinderCapture = 30 std::tuple<raw_ptr<Unwinder>, std::unique_ptr<UnwinderStateCapture>>; 31 32 // StackUnwindData is an implementation detail of StackSamplingProfiler. It 33 // contains data so that we can unwind stacks off the sampling thread. 34 class BASE_EXPORT StackUnwindData { 35 public: 36 explicit StackUnwindData(std::unique_ptr<ProfileBuilder> profile_builder); 37 ~StackUnwindData(); 38 profile_builder()39 ProfileBuilder* profile_builder() { return profile_builder_.get(); } 40 module_cache()41 ModuleCache* module_cache() { 42 DCHECK_CALLED_ON_VALID_SEQUENCE(worker_sequence_checker_); 43 return module_cache_; 44 } 45 46 // These are called by the SamplingThread. 47 void Initialize(std::vector<std::unique_ptr<Unwinder>> unwinders); 48 std::vector<UnwinderCapture> GetUnwinderSnapshot(); 49 void OnThreadPoolRunning(); 50 51 // This may be called by either: 52 // 1) the thread to sample if we haven't started sampling 53 // 2) the SamplingThread 54 void AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder); 55 56 private: 57 SEQUENCE_CHECKER(sampling_thread_sequence_checker_); 58 SEQUENCE_CHECKER(worker_sequence_checker_); 59 60 // Receives the sampling data and builds a CallStackProfile. 61 std::unique_ptr<ProfileBuilder> profile_builder_; 62 63 // Unwinders are stored in decreasing priority order. 64 base::circular_deque<std::unique_ptr<Unwinder>> unwinders_ 65 GUARDED_BY_CONTEXT(sampling_thread_sequence_checker_); 66 const raw_ptr<ModuleCache> module_cache_; 67 }; 68 69 } // namespace base 70 71 #endif // BASE_PROFILER_STACK_UNWIND_DATA_H_ 72