summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_report_sample.proto
blob: 8944fbef1e179da9b83fae6f7e954247de326ebe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * Copyright (C) 2022 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.
 */

// The file format generated by cmd_report_sample.proto is as below:
// char magic[10] = "SIMPLEPERF";
// LittleEndian16(version) = 1;
// LittleEndian32(record_size_0)
// message Record(record_0) (having record_size_0 bytes)
// LittleEndian32(record_size_1)
// message Record(record_1) (having record_size_1 bytes)
// ...
// LittleEndian32(record_size_N)
// message Record(record_N) (having record_size_N bytes)
// LittleEndian32(0)

syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package simpleperf_report_proto;
option java_package = "com.android.tools.profiler.proto";
option java_outer_classname = "SimpleperfReport";

message Sample {
  // Monotonic clock time in nanoseconds. On kernel < 4.1, it's perf clock instead.
  optional uint64 time = 1;
  optional int32 thread_id = 2;

  message CallChainEntry {
    // virtual address of the instruction in elf file
    optional uint64 vaddr_in_file = 1;

    // index of the elf file containing the instruction
    optional uint32 file_id = 2;

    // symbol_id refers to the name of the function containing the instruction.
    // If the function name is found, it is a valid index in the symbol table
    // of File with 'id' field being file_id, otherwise it is -1.
    optional int32 symbol_id = 3;

    enum ExecutionType {
      // methods belong to native libraries, AOT compiled JVM code and ART methods not used near
      // JVM methods
      NATIVE_METHOD = 0;
      INTERPRETED_JVM_METHOD = 1;
      JIT_JVM_METHOD = 2;
      // ART methods used near JVM methods. It's shown only when --show-art-frames is used.
      ART_METHOD = 3;
    }
    optional ExecutionType execution_type = 4 [default = NATIVE_METHOD];
  }

  repeated CallChainEntry callchain = 3;

  // Simpleperf generates one sample whenever a specified amount of events happen
  // while running a monitored thread. So each sample belongs to one event type.
  // Event type can be cpu-cycles, cpu-clock, sched:sched_switch or other types.
  // By using '-e' option, we can ask simpleperf to record samples for one or more
  // event types.
  // Each event type generates samples independently. But recording more event types
  // will cost more cpu time generating samples, which may affect the monitored threads
  // and sample lost rate.
  // event_count field shows the count of the events (belong to the sample's event type)
  // that have happened since last sample (belong to the sample's event type) for the
  // same thread. However, if there are lost samples between current sample and previous
  // sample, the event_count is the count of events from the last lost sample.
  optional uint64 event_count = 4;

  // An index in meta_info.event_type, shows which event type current sample belongs to.
  optional uint32 event_type_id = 5;

  message UnwindingResult {
    // error code provided by libunwindstack, in
    // https://cs.android.com/android/platform/superproject/+/master:system/unwinding/libunwindstack/include/unwindstack/Error.h
    optional uint32 raw_error_code = 1;
    // error addr provided by libunwindstack
    optional uint64 error_addr = 2;

    // error code interpreted by simpleperf
    enum ErrorCode {
      ERROR_NONE = 0;                  // No error
      ERROR_UNKNOWN = 1;               // Error not interpreted by simpleperf, see raw_error_code
      ERROR_NOT_ENOUGH_STACK = 2;      // Simpleperf doesn't record enough stack data
      ERROR_MEMORY_INVALID = 3;        // Memory read failed
      ERROR_UNWIND_INFO = 4;           // No debug info in binary to support unwinding
      ERROR_INVALID_MAP = 5;           // Unwind in an invalid map
      ERROR_MAX_FRAME_EXCEEDED = 6;    // Stopped at MAX_UNWINDING_FRAMES, which is 512.
      ERROR_REPEATED_FRAME = 7;        // The last frame has the same pc/sp as the next.
      ERROR_INVALID_ELF = 8;           // Unwind in an invalid elf file
    }
    optional ErrorCode error_code = 3;
  }

  // Unwinding result is provided for samples without a complete callchain, when recorded with
  // --keep-failed-unwinding-result or --keep-failed-unwinding-debug-info.
  optional UnwindingResult unwinding_result = 6;
}

message LostSituation {
  optional uint64 sample_count = 1;
  optional uint64 lost_count = 2;
}

message File {
  // unique id for each file, starting from 0, and add 1 each time.
  optional uint32 id = 1;

  // file path, like /system/lib/libc.so.
  optional string path = 2;

  // symbol table of the file.
  repeated string symbol = 3;

  // mangled symbol table of the file.
  repeated string mangled_symbol = 4;
}

message Thread {
  optional uint32 thread_id = 1;
  optional uint32 process_id = 2;
  optional string thread_name = 3;
}

message MetaInfo {
  repeated string event_type = 1;
  optional string app_package_name = 2;
  optional string app_type = 3;  // debuggable, profileable or non_profileable
  optional string android_sdk_version = 4;
  optional string android_build_type = 5;  // user, userdebug or eng

  // True if the profile is recorded with --trace-offcpu option.
  optional bool trace_offcpu = 6;
}

// Thread context switch info. It is available when MetaInfo.trace_offcpu = true.
message ContextSwitch {
  // If true, the thread is scheduled on cpu, otherwise it is scheduled off cpu.
  optional bool switch_on = 1;

  // Monotonic clock time in nanoseconds. On kernel < 4.1, it's perf clock instead.
  optional uint64 time = 2;
  optional uint32 thread_id = 3;
}

message Record {
  oneof record_data {
    Sample sample = 1;
    LostSituation lost = 2;
    File file = 3;
    Thread thread = 4;
    MetaInfo meta_info = 5;
    ContextSwitch context_switch = 6;
  }
}