summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2019-02-07 11:06:16 -0800
committerYabin Cui <yabinc@google.com>2019-02-14 11:09:33 -0800
commitd9121cec265ca1ecaea7fcf415ea5a0ddd39530e (patch)
tree005fc82eca26da3b3ac3d60f07f5b3c4f9e2f395 /simpleperf/cmd_record.cpp
parented1f0357906b3b92bc180b28a6c2fd1f9082fb67 (diff)
downloadextras-d9121cec265ca1ecaea7fcf415ea5a0ddd39530e.tar.gz
simpleperf: prepare for adding user api.
In record cmd, add --stdio-controls-profiling option to pause/resume profiling. It reads cmds from stdin, and writes replies to stdout. Add --log-to-android-buffer option to show simpleperf logs in logcat. Bug: 123717243 Test: run simpleperf through user api manually. Test: run simpleperf_unit_test. Change-Id: I6c32c669d003cbd670a45e6fd31f764656837111
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r--simpleperf/cmd_record.cpp53
1 files changed, 47 insertions, 6 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 1deaa597..6b45c3cd 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -212,6 +212,7 @@ class RecordCommand : public Command {
" Default is unlimited.\n"
"--start_profiling_fd fd_no After starting profiling, write \"STARTED\" to\n"
" <fd_no>, then close <fd_no>.\n"
+"--stdio-controls-profiling Use stdin/stdout to pause/resume profiling.\n"
"--symfs <dir> Look for files with symbols relative to this directory.\n"
" This option is used to provide files with symbol table and\n"
" debug information, which are used for unwinding and dumping symbols.\n"
@@ -240,7 +241,6 @@ class RecordCommand : public Command {
record_filename_("perf.data"),
sample_record_count_(0),
lost_record_count_(0),
- start_profiling_fd_(-1),
in_app_context_(false),
trace_offcpu_(false),
exclude_kernel_callchain_(false),
@@ -280,6 +280,7 @@ class RecordCommand : public Command {
bool SaveRecordAfterUnwinding(Record* record);
bool SaveRecordWithoutUnwinding(Record* record);
bool ProcessJITDebugInfo(const std::vector<JITDebugInfo>& debug_info, bool sync_kernel_records);
+ bool ProcessControlCmd(IOEventLoop* loop);
void UpdateRecord(Record* record);
bool UnwindRecord(SampleRecord& r);
@@ -318,7 +319,9 @@ class RecordCommand : public Command {
uint64_t sample_record_count_;
uint64_t lost_record_count_;
- int start_profiling_fd_;
+ android::base::unique_fd start_profiling_fd_;
+ bool stdio_controls_profiling_ = false;
+
std::string app_package_name_;
bool in_app_context_;
bool trace_offcpu_;
@@ -506,6 +509,11 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
return false;
}
}
+ if (stdio_controls_profiling_) {
+ if (!loop->AddReadEvent(0, [&]() { return ProcessControlCmd(loop); })) {
+ return false;
+ }
+ }
if (jit_debug_reader_) {
auto callback = [this](const std::vector<JITDebugInfo>& debug_info, bool sync_kernel_records) {
return ProcessJITDebugInfo(debug_info, sync_kernel_records);
@@ -539,11 +547,15 @@ bool RecordCommand::DoRecording(Workload* workload) {
if (workload != nullptr && !workload->IsStarted() && !workload->Start()) {
return false;
}
- if (start_profiling_fd_ != -1) {
+ if (start_profiling_fd_.get() != -1) {
if (!android::base::WriteStringToFd("STARTED", start_profiling_fd_)) {
PLOG(ERROR) << "failed to write to start_profiling_fd_";
}
- close(start_profiling_fd_);
+ start_profiling_fd_.reset();
+ }
+ if (stdio_controls_profiling_) {
+ printf("started\n");
+ fflush(stdout);
}
if (!event_selection_set_.GetIOEventLoop()->RunLoop()) {
return false;
@@ -852,9 +864,13 @@ bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
return false;
}
} else if (args[i] == "--start_profiling_fd") {
- if (!GetUintOption(args, &i, &start_profiling_fd_)) {
+ int fd;
+ if (!GetUintOption(args, &i, &fd)) {
return false;
}
+ start_profiling_fd_.reset(fd);
+ } else if (args[i] == "--stdio-controls-profiling") {
+ stdio_controls_profiling_ = true;
} else if (args[i] == "--stop-signal-fd") {
int fd;
if (!GetUintOption(args, &i, &fd)) {
@@ -964,7 +980,7 @@ bool RecordCommand::AdjustPerfEventLimit() {
set_prop = true;
}
- if (GetAndroidVersion() >= kAndroidVersionP + 1 && set_prop) {
+ if (GetAndroidVersion() >= kAndroidVersionP + 1 && set_prop && !in_app_context_) {
return SetPerfEventLimits(std::max(max_sample_freq_, cur_max_freq), cpu_time_max_percent_,
std::max(mlock_kb, cur_mlock_kb));
}
@@ -1297,6 +1313,31 @@ bool RecordCommand::ProcessJITDebugInfo(const std::vector<JITDebugInfo>& debug_i
return true;
}
+bool RecordCommand::ProcessControlCmd(IOEventLoop* loop) {
+ char* line = nullptr;
+ size_t line_length = 0;
+ if (getline(&line, &line_length, stdin) == -1) {
+ free(line);
+ // When the simpleperf Java API destroys the simpleperf process, it also closes the stdin pipe.
+ // So we may see EOF of stdin.
+ return loop->ExitLoop();
+ }
+ std::string cmd = android::base::Trim(line);
+ free(line);
+ LOG(DEBUG) << "process control cmd: " << cmd;
+ bool result = false;
+ if (cmd == "pause") {
+ result = event_selection_set_.SetEnableEvents(false);
+ } else if (cmd == "resume") {
+ result = event_selection_set_.SetEnableEvents(true);
+ } else {
+ LOG(ERROR) << "unknown control cmd: " << cmd;
+ }
+ printf("%s\n", result ? "ok" : "error");
+ fflush(stdout);
+ return result;
+}
+
template <class RecordType>
void UpdateMmapRecordForEmbeddedPath(RecordType& r, bool has_prot, uint32_t prot) {
if (r.InKernel()) {