Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support importing simpleperf trace files from Android Studio #5212

Merged
merged 13 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
src/profile-logic/import/proto
src/types/libdef/npm
docs-user
coverage
1 change: 1 addition & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ esproposal.optional_chaining=enable
[ignore]
<PROJECT_ROOT>/node_modules/.*
<PROJECT_ROOT>/dist/.*
src/profile-logic/import/proto/.*

[libs]
src/types/libdef
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
src/profile-logic/import/proto
src/types/libdef/npm
docs-user
src/test/fixtures/upgrades
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"engines": {
"node": ">= 18.16 < 19"
"node": ">= 18.16"
nisargjhaveri marked this conversation as resolved.
Show resolved Hide resolved
},
"scripts": {
"build:clean": "rimraf dist && mkdirp dist",
Expand All @@ -28,6 +28,7 @@
"flow-stop": "flow stop",
"flow-coverage": "flow-coverage-report -i 'src/**/*.js' -t html -t text",
"flow-generate-libdefs": "flow-typed install --libdefDir src/types/libdef",
"protoc": "pbjs -t static-module -w commonjs -o ./src/profile-logic/import/proto/simpleperf_report.js ./src/profile-logic/import/proto/simpleperf_report.proto",
nisargjhaveri marked this conversation as resolved.
Show resolved Hide resolved
"license-check": "devtools-license-check",
"preinstall": "node bin/pre-install.js",
"publish": "rimraf public_html && cp -r dist public_html",
Expand Down Expand Up @@ -78,12 +79,14 @@
"gecko-profiler-demangle": "^0.3.3",
"idb": "^8.0.0",
"jszip": "^3.10.1",
"long": "^5.2.3",
"memoize-immutable": "^3.0.0",
"memoize-one": "^6.0.0",
"minimist": "^1.2.8",
"mixedtuplemap": "^1.0.0",
"namedtuplemap": "^1.0.0",
"photon-colors": "^3.3.2",
"protobufjs": "^7.4.0",
"query-string": "^9.1.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down Expand Up @@ -158,6 +161,7 @@
"postcss": "^8.4.47",
"postcss-loader": "^8.1.1",
"prettier": "^3.3.3",
"protobufjs-cli": "^1.1.3",
"raw-loader": "^4.0.2",
"rimraf": "^5.0.10",
"style-loader": "^4.0.0",
Expand Down
2,892 changes: 2,892 additions & 0 deletions src/profile-logic/import/proto/simpleperf_report.js

Large diffs are not rendered by default.

166 changes: 166 additions & 0 deletions src/profile-logic/import/proto/simpleperf_report.proto
nisargjhaveri marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// Taken from https://cs.android.com/android/platform/superproject/main/+/main:system/extras/simpleperf/cmd_report_sample.proto;drc=58b18e6dd91279cf9fb53c44f232c3be58375303
/*
* 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;
}
}
Loading