OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 // Defines StructTraits specializations for translating between mojo types and | |
6 // base::StackSamplingProfiler types, with data validity checks. | |
7 | |
8 #ifndef COMPONENTS_METRICS_CALL_STACK_PROFILE_STRUCT_TRAITS_H_ | |
9 #define COMPONENTS_METRICS_CALL_STACK_PROFILE_STRUCT_TRAITS_H_ | |
10 | |
11 #include <vector> | |
12 | |
13 #include "base/files/file_path.h" | |
14 #include "base/profiler/stack_sampling_profiler.h" | |
15 #include "components/metrics/public/interfaces/call_stack_profile_collector.mojo m.h" | |
16 | |
17 namespace mojo { | |
18 | |
19 template <> | |
20 struct StructTraits<metrics::mojom::CallStackModule, | |
21 base::StackSamplingProfiler::Module> { | |
22 static uint64_t base_address( | |
23 const base::StackSamplingProfiler::Module& module) { | |
24 return module.base_address; | |
25 } | |
26 static const std::string& id( | |
27 const base::StackSamplingProfiler::Module& module) { | |
28 return module.id; | |
29 } | |
30 static const base::FilePath& filename( | |
31 const base::StackSamplingProfiler::Module& module) { | |
32 return module.filename; | |
33 } | |
34 | |
35 static bool Read(metrics::mojom::CallStackModuleDataView data, | |
36 base::StackSamplingProfiler::Module* out) { | |
37 std::string id; | |
38 base::FilePath filename; | |
39 if (!data.ReadId(&id) || !data.ReadFilename(&filename)) | |
Ilya Sherman
2016/08/18 07:59:18
Tom didn't comment on this, so it's probably not a
Mike Wittman
2016/08/18 17:49:19
The only use made of the filename is to generate a
Ilya Sherman
2016/08/18 21:39:49
My understanding is that it's undesirable to allow
| |
40 return false; | |
41 | |
42 *out = | |
43 base::StackSamplingProfiler::Module(data.base_address(), id, filename); | |
44 return true; | |
45 } | |
46 }; | |
47 | |
48 template <> | |
49 struct StructTraits<metrics::mojom::CallStackFrame, | |
50 base::StackSamplingProfiler::Frame> { | |
51 static uint64_t instruction_pointer( | |
52 const base::StackSamplingProfiler::Frame& frame) { | |
53 return frame.instruction_pointer; | |
54 } | |
55 static uint64_t module_index( | |
56 const base::StackSamplingProfiler::Frame& frame) { | |
57 return frame.module_index == | |
58 base::StackSamplingProfiler::Frame::kUnknownModuleIndex ? | |
59 static_cast<uint64_t>(-1) : | |
60 frame.module_index; | |
61 } | |
62 | |
63 static bool Read(metrics::mojom::CallStackFrameDataView data, | |
64 base::StackSamplingProfiler::Frame* out) { | |
65 size_t module_index = data.module_index() == static_cast<uint64_t>(-1) ? | |
66 base::StackSamplingProfiler::Frame::kUnknownModuleIndex : | |
67 data.module_index(); | |
68 | |
69 // The module_index field must be checked to be in the valid range when | |
70 // reading CallStackProfile. | |
Ilya Sherman
2016/08/18 07:59:18
Sorry, I'm not following what this comment means.
Mike Wittman
2016/08/18 17:49:19
Clarified the comment.
Frames are not meaningful
| |
71 *out = base::StackSamplingProfiler::Frame(data.instruction_pointer(), | |
72 module_index); | |
73 return true; | |
74 } | |
75 }; | |
76 | |
77 template <> | |
78 struct StructTraits<metrics::mojom::CallStackProfile, | |
79 base::StackSamplingProfiler::CallStackProfile> { | |
80 static const std::vector<base::StackSamplingProfiler::Module>& modules( | |
81 const base::StackSamplingProfiler::CallStackProfile& profile) { | |
82 return profile.modules; | |
83 } | |
84 static const std::vector<base::StackSamplingProfiler::Sample>& samples( | |
85 const base::StackSamplingProfiler::CallStackProfile& profile) { | |
86 return profile.samples; | |
87 } | |
88 static const base::TimeDelta profile_duration( | |
89 const base::StackSamplingProfiler::CallStackProfile& profile) { | |
90 return profile.profile_duration; | |
91 } | |
92 static const base::TimeDelta sampling_period( | |
93 const base::StackSamplingProfiler::CallStackProfile& profile) { | |
94 return profile.sampling_period; | |
95 } | |
96 | |
97 static bool ValidateSamples( | |
98 std::vector<base::StackSamplingProfiler::Sample> samples, | |
99 size_t module_count) { | |
100 for (const base::StackSamplingProfiler::Sample& sample : samples) { | |
101 for (const base::StackSamplingProfiler::Frame& frame : sample) { | |
102 if (frame.module_index >= module_count && frame.module_index != | |
Ilya Sherman
2016/08/18 07:59:18
nit: This is a weird spot to break the line. Is t
Mike Wittman
2016/08/18 17:49:19
Updated formatting to clang output.
| |
103 base::StackSamplingProfiler::Frame::kUnknownModuleIndex) | |
104 return false; | |
105 } | |
106 } | |
107 return true; | |
108 } | |
109 | |
110 static bool Read(metrics::mojom::CallStackProfileDataView data, | |
111 base::StackSamplingProfiler::CallStackProfile* out) { | |
112 std::vector<base::StackSamplingProfiler::Module> modules; | |
113 std::vector<base::StackSamplingProfiler::Sample> samples; | |
114 base::TimeDelta profile_duration, sampling_period; | |
115 if (!data.ReadModules(&modules) || !data.ReadSamples(&samples) || | |
116 !data.ReadProfileDuration(&profile_duration) || | |
117 !data.ReadSamplingPeriod(&sampling_period) || | |
118 !ValidateSamples(samples, modules.size())) | |
119 return false; | |
120 | |
121 *out = base::StackSamplingProfiler::CallStackProfile(); | |
122 out->modules = std::move(modules); | |
123 out->samples = std::move(samples); | |
124 out->profile_duration = profile_duration; | |
125 out->sampling_period = sampling_period; | |
126 return true; | |
127 } | |
128 }; | |
129 | |
130 } // mojo | |
131 | |
132 #endif // COMPONENTS_METRICS_CALL_STACK_PROFILE_STRUCT_TRAITS_H_ | |
OLD | NEW |