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