|  | // 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"; | 
|  |  | 
|  | package perftools.profiles; | 
|  |  | 
|  | option java_package = "com.google.perftools.profiles"; | 
|  | option java_outer_classname = "ProfileProto"; | 
|  |  | 
|  | 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. | 
|  | // If 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; | 
|  | } | 
|  |  | 
|  | 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; | 
|  | } |