blob: 0f22f1c8498a90f491becbf2a9e9a93e65ce7533 [file] [log] [blame]
Xi Cheng859dfcc2018-07-02 23:06:411// Copyright 2018 The Chromium Authors. All rights reserved.
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 COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_
6#define COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_
7
Mike Wittmancb1067c2019-01-24 19:04:008#include <limits>
Xi Cheng859dfcc2018-07-02 23:06:419#include <map>
Xi Chenge91f6fd2018-08-14 16:34:5610#include <vector>
Xi Cheng859dfcc2018-07-02 23:06:4111
Xi Cheng2e07c5d2018-07-03 21:01:2912#include "base/callback.h"
Xi Cheng367942c2018-08-03 02:43:1913#include "base/profiler/stack_sampling_profiler.h"
Xi Chengeb46484d2018-08-15 01:00:2814#include "base/sampling_heap_profiler/module_cache.h"
Xi Cheng9358aa092018-08-28 16:11:1215#include "base/time/time.h"
Xi Cheng4dec7e42018-08-10 16:54:1116#include "components/metrics/call_stack_profile_params.h"
Xi Cheng9358aa092018-08-28 16:11:1217#include "components/metrics/child_call_stack_profile_collector.h"
Xi Cheng4dec7e42018-08-10 16:54:1118#include "third_party/metrics_proto/sampled_profile.pb.h"
Xi Cheng2e07c5d2018-07-03 21:01:2919
Xi Chengcbeecd902018-07-05 01:34:5620namespace metrics {
21
Mike Wittmancb1067c2019-01-24 19:04:0022// Interface that allows the CallStackProfileBuilder to provide ids for distinct
23// work items. Samples with the same id are tagged as coming from the same work
24// item in the recorded samples.
25class WorkIdRecorder {
26 public:
27 WorkIdRecorder() = default;
28 virtual ~WorkIdRecorder() = default;
29
30 // This function is invoked on the profiler thread while the target thread is
31 // suspended so must not take any locks, including indirectly through use of
32 // heap allocation, LOG, CHECK, or DCHECK.
33 virtual unsigned int RecordWorkId() const = 0;
34
35 WorkIdRecorder(const WorkIdRecorder&) = delete;
36 WorkIdRecorder& operator=(const WorkIdRecorder&) = delete;
37};
38
Xi Cheng9358aa092018-08-28 16:11:1239// An instance of the class is meant to be passed to base::StackSamplingProfiler
40// to collect profiles. The profiles collected are uploaded via the metrics log.
Xi Chengb2e858e52018-09-11 20:58:0341//
42// This uses the new StackSample encoding rather than the legacy Sample
43// encoding.
Xi Cheng859dfcc2018-07-02 23:06:4144class CallStackProfileBuilder
45 : public base::StackSamplingProfiler::ProfileBuilder {
46 public:
Xi Cheng9358aa092018-08-28 16:11:1247 // |completed_callback| is made when sampling a profile completes. Other
48 // threads, including the UI thread, may block on callback completion so this
49 // should run as quickly as possible.
50 //
51 // IMPORTANT NOTE: The callback is invoked on a thread the profiler
52 // constructs, rather than on the thread used to construct the profiler, and
53 // thus the callback must be callable on any thread.
Alexei Filippovdbbde602018-09-08 00:17:2654 explicit CallStackProfileBuilder(
Xi Cheng9358aa092018-08-28 16:11:1255 const CallStackProfileParams& profile_params,
Mike Wittmancb1067c2019-01-24 19:04:0056 const WorkIdRecorder* work_id_recorder = nullptr,
Xi Cheng9358aa092018-08-28 16:11:1257 base::OnceClosure completed_callback = base::OnceClosure());
Xi Cheng859dfcc2018-07-02 23:06:4158
59 ~CallStackProfileBuilder() override;
60
61 // base::StackSamplingProfiler::ProfileBuilder:
Mike Wittmancb1067c2019-01-24 19:04:0062 void RecordMetadata() override;
Xi Chenge91f6fd2018-08-14 16:34:5663 void OnSampleCompleted(
64 std::vector<base::StackSamplingProfiler::Frame> frames) override;
Xi Cheng859dfcc2018-07-02 23:06:4165 void OnProfileCompleted(base::TimeDelta profile_duration,
66 base::TimeDelta sampling_period) override;
67
Mike Wittman2943c9c72018-08-31 19:28:5768 // Sets the callback to use for reporting browser process profiles. This
69 // indirection is required to avoid a dependency on unnecessary metrics code
70 // in child processes.
71 static void SetBrowserProcessReceiverCallback(
72 const base::RepeatingCallback<void(base::TimeTicks, SampledProfile)>&
73 callback);
74
Xi Cheng9358aa092018-08-28 16:11:1275 // Sets the CallStackProfileCollector interface from |browser_interface|.
76 // This function must be called within child processes.
77 static void SetParentProfileCollectorForChildProcess(
78 metrics::mojom::CallStackProfileCollectorPtr browser_interface);
79
80 protected:
81 // Test seam.
82 virtual void PassProfilesToMetricsProvider(SampledProfile sampled_profile);
83
Xi Cheng859dfcc2018-07-02 23:06:4184 private:
Xi Chengb2e858e52018-09-11 20:58:0385 // The functor for Stack comparison.
86 struct StackComparer {
87 bool operator()(const CallStackProfile::Stack* stack1,
88 const CallStackProfile::Stack* stack2) const;
89 };
Xi Cheng859dfcc2018-07-02 23:06:4190
Mike Wittmancb1067c2019-01-24 19:04:0091 unsigned int last_work_id_ = std::numeric_limits<unsigned int>::max();
92 bool is_continued_work_ = false;
93 const WorkIdRecorder* const work_id_recorder_;
94
Xi Chengb2e858e52018-09-11 20:58:0395 // The SampledProfile protobuf message which contains the collected stack
96 // samples.
97 SampledProfile sampled_profile_;
Xi Cheng859dfcc2018-07-02 23:06:4198
Xi Chengb2e858e52018-09-11 20:58:0399 // The indexes of stacks, indexed by stack's address.
100 std::map<const CallStackProfile::Stack*, int, StackComparer> stack_index_;
Xi Chenge91f6fd2018-08-14 16:34:56101
102 // The indexes of modules, indexed by module's base_address.
Xi Cheng859dfcc2018-07-02 23:06:41103 std::map<uintptr_t, size_t> module_index_;
104
Xi Chenge91f6fd2018-08-14 16:34:56105 // The distinct modules in the current profile.
Xi Chengeb46484d2018-08-15 01:00:28106 std::vector<base::ModuleCache::Module> modules_;
Xi Chenge91f6fd2018-08-14 16:34:56107
Xi Cheng859dfcc2018-07-02 23:06:41108 // Callback made when sampling a profile completes.
Xi Cheng9358aa092018-08-28 16:11:12109 base::OnceClosure completed_callback_;
Xi Cheng859dfcc2018-07-02 23:06:41110
Xi Cheng9358aa092018-08-28 16:11:12111 // The start time of a profile collection.
112 const base::TimeTicks profile_start_time_;
113
Xi Cheng859dfcc2018-07-02 23:06:41114 DISALLOW_COPY_AND_ASSIGN(CallStackProfileBuilder);
115};
116
Xi Chengcbeecd902018-07-05 01:34:56117} // namespace metrics
118
Xi Cheng859dfcc2018-07-02 23:06:41119#endif // COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_