| // Copyright (C) 2018 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // Profile is a common stacktrace profile format. |
| // |
| // Measurements represented with this format should follow the |
| // following conventions: |
| // |
| // - Consumers should treat unset optional fields as if they had been |
| // set with their default value. |
| // |
| // - When possible, measurements should be stored in "unsampled" form |
| // that is most useful to humans. There should be enough |
| // information present to determine the original sampled values. |
| // |
| // - On-disk, the serialized proto must be gzip-compressed. |
| // |
| // - The profile is represented as a set of samples, where each sample |
| // references a sequence of locations, and where each location belongs |
| // to a mapping. |
| // - There is a N->1 relationship from sample.location_id entries to |
| // locations. For every sample.location_id entry there must be a |
| // unique Location with that id. |
| // - There is an optional N->1 relationship from locations to |
| // mappings. For every nonzero Location.mapping_id there must be a |
| // unique Mapping with that id. |
| |
| syntax = "proto3"; |
| |
| // This is in perfetto.third_party to avoid clashing with potential other |
| // copies of this proto. |
| package perfetto.third_party.perftools.profiles; |
| |
| option java_package = "com.google.perftools.profiles"; |
| option java_outer_classname = "ProfileProto"; |
| |
| // Perfetto Changes =========================================================== |
| // 1. Add optimize_for = LITE_RUNTIME |
| option optimize_for = LITE_RUNTIME; |
| // ============================================================================ |
| |
| message Profile { |
| // A description of the samples associated with each Sample.value. |
| // For a cpu profile this might be: |
| // [["cpu","nanoseconds"]] or [["wall","seconds"]] or [["syscall","count"]] |
| // For a heap profile, this might be: |
| // [["allocations","count"], ["space","bytes"]], |
| // If one of the values represents the number of events represented |
| // by the sample, by convention it should be at index 0 and use |
| // sample_type.unit == "count". |
| repeated ValueType sample_type = 1; |
| // The set of samples recorded in this profile. |
| repeated Sample sample = 2; |
| // Mapping from address ranges to the image/binary/library mapped |
| // into that address range. mapping[0] will be the main binary. |
| repeated Mapping mapping = 3; |
| // Useful program location |
| repeated Location location = 4; |
| // Functions referenced by locations |
| repeated Function function = 5; |
| // A common table for strings referenced by various messages. |
| // string_table[0] must always be "". |
| repeated string string_table = 6; |
| // frames with Function.function_name fully matching the following |
| // regexp will be dropped from the samples, along with their successors. |
| int64 drop_frames = 7; // Index into string table. |
| // frames with Function.function_name fully matching the following |
| // regexp will be kept, even if it matches drop_functions. |
| int64 keep_frames = 8; // Index into string table. |
| |
| // The following fields are informational, do not affect |
| // interpretation of results. |
| |
| // Time of collection (UTC) represented as nanoseconds past the epoch. |
| int64 time_nanos = 9; |
| // Duration of the profile, if a duration makes sense. |
| int64 duration_nanos = 10; |
| // The kind of events between sampled ocurrences. |
| // e.g [ "cpu","cycles" ] or [ "heap","bytes" ] |
| ValueType period_type = 11; |
| // The number of events between sampled occurrences. |
| int64 period = 12; |
| // Freeform text associated to the profile. |
| repeated int64 comment = 13; // Indices into string table. |
| // Index into the string table of the type of the preferred sample |
| // value. If unset, clients should default to the last sample value. |
| int64 default_sample_type = 14; |
| } |
| |
| // ValueType describes the semantics and measurement units of a value. |
| message ValueType { |
| int64 type = 1; // Index into string table. |
| int64 unit = 2; // Index into string table. |
| } |
| |
| // Each Sample records values encountered in some program |
| // context. The program context is typically a stack trace, perhaps |
| // augmented with auxiliary information like the thread-id, some |
| // indicator of a higher level request being handled etc. |
| message Sample { |
| // The ids recorded here correspond to a Profile.location.id. |
| // The leaf is at location_id[0]. |
| repeated uint64 location_id = 1; |
| // The type and unit of each value is defined by the corresponding |
| // entry in Profile.sample_type. All samples must have the same |
| // number of values, the same as the length of Profile.sample_type. |
| // When aggregating multiple samples into a single sample, the |
| // result has a list of values that is the elemntwise sum of the |
| // lists of the originals. |
| repeated int64 value = 2; |
| // label includes additional context for this sample. It can include |
| // things like a thread id, allocation size, etc |
| repeated Label label = 3; |
| } |
| |
| message Label { |
| int64 key = 1; // Index into string table |
| |
| // At most one of the following must be present |
| int64 str = 2; // Index into string table |
| int64 num = 3; |
| |
| // Should only be present when num is present. |
| // Specifies the units of num. |
| // Use arbitrary string (for example, "requests") as a custom count unit. |
| // If no unit is specified, consumer may apply heuristic to deduce the unit. |
| // Consumers may also interpret units like "bytes" and "kilobytes" as memory |
| // units and units like "seconds" and "nanoseconds" as time units, |
| // and apply appropriate unit conversions to these. |
| int64 num_unit = 4; // Index into string table |
| } |
| |
| message Mapping { |
| // Unique nonzero id for the mapping. |
| uint64 id = 1; |
| // Address at which the binary (or DLL) is loaded into memory. |
| uint64 memory_start = 2; |
| // The limit of the address range occupied by this mapping. |
| uint64 memory_limit = 3; |
| // Offset in the binary that corresponds to the first mapped address. |
| uint64 file_offset = 4; |
| // The object this entry is loaded from. This can be a filename on |
| // disk for the main binary and shared libraries, or virtual |
| // abstractions like "[vdso]". |
| int64 filename = 5; // Index into string table |
| // A string that uniquely identifies a particular program version |
| // with high probability. E.g., for binaries generated by GNU tools, |
| // it could be the contents of the .note.gnu.build-id field. |
| int64 build_id = 6; // Index into string table |
| |
| // The following fields indicate the resolution of symbolic info. |
| bool has_functions = 7; |
| bool has_filenames = 8; |
| bool has_line_numbers = 9; |
| bool has_inline_frames = 10; |
| } |
| |
| // Describes function and line table debug information. |
| message Location { |
| // Unique nonzero id for the location. A profile could use |
| // instruction addresses or any integer sequence as ids. |
| uint64 id = 1; |
| // The id of the corresponding profile.Mapping for this location. |
| // It can be unset if the mapping is unknown or not applicable for |
| // this profile type. |
| uint64 mapping_id = 2; |
| // The instruction address for this location, if available. It |
| // should be within [Mapping.memory_start...Mapping.memory_limit] |
| // for the corresponding mapping. A non-leaf address may be in the |
| // middle of a call instruction. It is up to display tools to find |
| // the beginning of the instruction if necessary. |
| uint64 address = 3; |
| // Multiple line indicates this location has inlined functions, |
| // where the last entry represents the caller into which the |
| // preceding entries were inlined. |
| // |
| // E.g., if memcpy() is inlined into printf: |
| // line[0].function_name == "memcpy" |
| // line[1].function_name == "printf" |
| repeated Line line = 4; |
| // Provides an indication that multiple symbols map to this location's |
| // address, for example due to identical code folding by the linker. In that |
| // case the line information above represents one of the multiple |
| // symbols. This field must be recomputed when the symbolization state of the |
| // profile changes. |
| bool is_folded = 5; |
| } |
| |
| message Line { |
| // The id of the corresponding profile.Function for this line. |
| uint64 function_id = 1; |
| // Line number in source code. |
| int64 line = 2; |
| } |
| |
| message Function { |
| // Unique nonzero id for the function. |
| uint64 id = 1; |
| // Name of the function, in human-readable form if available. |
| int64 name = 2; // Index into string table |
| // Name of the function, as identified by the system. |
| // For instance, it can be a C++ mangled name. |
| int64 system_name = 3; // Index into string table |
| // Source file containing the function. |
| int64 filename = 4; // Index into string table |
| // Line number in source file. |
| int64 start_line = 5; |
| } |