1// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Profile is a common stacktrace profile format.
16//
17// Measurements represented with this format should follow the
18// following conventions:
19//
20// - Consumers should treat unset optional fields as if they had been
21//   set with their default value.
22//
23// - When possible, measurements should be stored in "unsampled" form
24//   that is most useful to humans.  There should be enough
25//   information present to determine the original sampled values.
26//
27// - On-disk, the serialized proto must be gzip-compressed.
28//
29// - The profile is represented as a set of samples, where each sample
30//   references a sequence of locations, and where each location belongs
31//   to a mapping.
32// - There is a N->1 relationship from sample.location_id entries to
33//   locations. For every sample.location_id entry there must be a
34//   unique Location with that id.
35// - There is an optional N->1 relationship from locations to
36//   mappings. For every nonzero Location.mapping_id there must be a
37//   unique Mapping with that id.
38
39syntax = "proto3";
40
41// This is in perfetto.third_party to avoid clashing with potential other
42// copies of this proto.
43package perfetto.third_party.perftools.profiles;
44
45option java_package = "com.google.perftools.profiles";
46option java_outer_classname = "ProfileProto";
47
48message Profile {
49  // A description of the samples associated with each Sample.value.
50  // For a cpu profile this might be:
51  //   [["cpu","nanoseconds"]] or [["wall","seconds"]] or [["syscall","count"]]
52  // For a heap profile, this might be:
53  //   [["allocations","count"], ["space","bytes"]],
54  // If one of the values represents the number of events represented
55  // by the sample, by convention it should be at index 0 and use
56  // sample_type.unit == "count".
57  repeated ValueType sample_type = 1;
58  // The set of samples recorded in this profile.
59  repeated Sample sample = 2;
60  // Mapping from address ranges to the image/binary/library mapped
61  // into that address range.  mapping[0] will be the main binary.
62  repeated Mapping mapping = 3;
63  // Useful program location
64  repeated Location location = 4;
65  // Functions referenced by locations
66  repeated Function function = 5;
67  // A common table for strings referenced by various messages.
68  // string_table[0] must always be "".
69  repeated string string_table = 6;
70  // frames with Function.function_name fully matching the following
71  // regexp will be dropped from the samples, along with their successors.
72  // Index into string table.
73  int64 drop_frames = 7;
74  // frames with Function.function_name fully matching the following
75  // regexp will be kept, even if it matches drop_functions.
76  // Index into string table.
77  int64 keep_frames = 8;
78
79  // The following fields are informational, do not affect
80  // interpretation of results.
81
82  // Time of collection (UTC) represented as nanoseconds past the epoch.
83  int64 time_nanos = 9;
84  // Duration of the profile, if a duration makes sense.
85  int64 duration_nanos = 10;
86  // The kind of events between sampled ocurrences.
87  // e.g [ "cpu","cycles" ] or [ "heap","bytes" ]
88  ValueType period_type = 11;
89  // The number of events between sampled occurrences.
90  int64 period = 12;
91  // Freeform text associated to the profile.
92  // Indices into string table.
93  repeated int64 comment = 13;
94  // Index into the string table of the type of the preferred sample
95  // value. If unset, clients should default to the last sample value.
96  int64 default_sample_type = 14;
97}
98
99// ValueType describes the semantics and measurement units of a value.
100message ValueType {
101  // Index into string table.
102  int64 type = 1;
103  // Index into string table.
104  int64 unit = 2;
105}
106
107// Each Sample records values encountered in some program
108// context. The program context is typically a stack trace, perhaps
109// augmented with auxiliary information like the thread-id, some
110// indicator of a higher level request being handled etc.
111message Sample {
112  // The ids recorded here correspond to a Profile.location.id.
113  // The leaf is at location_id[0].
114  repeated uint64 location_id = 1;
115  // The type and unit of each value is defined by the corresponding
116  // entry in Profile.sample_type. All samples must have the same
117  // number of values, the same as the length of Profile.sample_type.
118  // When aggregating multiple samples into a single sample, the
119  // result has a list of values that is the elemntwise sum of the
120  // lists of the originals.
121  repeated int64 value = 2;
122  // label includes additional context for this sample. It can include
123  // things like a thread id, allocation size, etc
124  repeated Label label = 3;
125}
126
127message Label {
128  // Index into string table
129  int64 key = 1;
130
131  // At most one of the following must be present
132
133  // Index into string table
134  int64 str = 2;
135
136  int64 num = 3;
137
138  // Should only be present when num is present.
139  // Specifies the units of num.
140  // Use arbitrary string (for example, "requests") as a custom count unit.
141  // If no unit is specified, consumer may apply heuristic to deduce the unit.
142  // Consumers may also  interpret units like "bytes" and "kilobytes" as memory
143  // units and units like "seconds" and "nanoseconds" as time units,
144  // and apply appropriate unit conversions to these.
145
146  // Index into string table
147  int64 num_unit = 4;
148}
149
150message Mapping {
151  // Unique nonzero id for the mapping.
152  uint64 id = 1;
153  // Address at which the binary (or DLL) is loaded into memory.
154  uint64 memory_start = 2;
155  // The limit of the address range occupied by this mapping.
156  uint64 memory_limit = 3;
157  // Offset in the binary that corresponds to the first mapped address.
158  uint64 file_offset = 4;
159  // The object this entry is loaded from.  This can be a filename on
160  // disk for the main binary and shared libraries, or virtual
161  // abstractions like "[vdso]".
162  // Index into string table
163  int64 filename = 5;
164  // A string that uniquely identifies a particular program version
165  // with high probability. E.g., for binaries generated by GNU tools,
166  // it could be the contents of the .note.gnu.build-id field.
167  // Index into string table
168  int64 build_id = 6;
169
170  // The following fields indicate the resolution of symbolic info.
171  bool has_functions = 7;
172  bool has_filenames = 8;
173  bool has_line_numbers = 9;
174  bool has_inline_frames = 10;
175}
176
177// Describes function and line table debug information.
178message Location {
179  // Unique nonzero id for the location.  A profile could use
180  // instruction addresses or any integer sequence as ids.
181  uint64 id = 1;
182  // The id of the corresponding profile.Mapping for this location.
183  // It can be unset if the mapping is unknown or not applicable for
184  // this profile type.
185  uint64 mapping_id = 2;
186  // The instruction address for this location, if available.  It
187  // should be within [Mapping.memory_start...Mapping.memory_limit]
188  // for the corresponding mapping. A non-leaf address may be in the
189  // middle of a call instruction. It is up to display tools to find
190  // the beginning of the instruction if necessary.
191  uint64 address = 3;
192  // Multiple line indicates this location has inlined functions,
193  // where the last entry represents the caller into which the
194  // preceding entries were inlined.
195  //
196  // E.g., if memcpy() is inlined into printf:
197  //    line[0].function_name == "memcpy"
198  //    line[1].function_name == "printf"
199  repeated Line line = 4;
200  // Provides an indication that multiple symbols map to this location's
201  // address, for example due to identical code folding by the linker. In that
202  // case the line information above represents one of the multiple
203  // symbols. This field must be recomputed when the symbolization state of the
204  // profile changes.
205  bool is_folded = 5;
206}
207
208message Line {
209  // The id of the corresponding profile.Function for this line.
210  uint64 function_id = 1;
211  // Line number in source code.
212  int64 line = 2;
213}
214
215message Function {
216  // Unique nonzero id for the function.
217  uint64 id = 1;
218  // Name of the function, in human-readable form if available.
219  // Index into string table
220  int64 name = 2;
221  // Name of the function, as identified by the system.
222  // For instance, it can be a C++ mangled name.
223  // Index into string table
224  int64 system_name = 3;
225  // Source file containing the function.
226  // Index into string table
227  int64 filename = 4;
228  // Line number in source file.
229  int64 start_line = 5;
230}
231