diff options
author | Yabin Cui <yabinc@google.com> | 2019-02-07 11:06:16 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2019-02-14 11:09:33 -0800 |
commit | d9121cec265ca1ecaea7fcf415ea5a0ddd39530e (patch) | |
tree | 005fc82eca26da3b3ac3d60f07f5b3c4f9e2f395 /simpleperf/cmd_record.cpp | |
parent | ed1f0357906b3b92bc180b28a6c2fd1f9082fb67 (diff) | |
download | extras-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.cpp | 53 |
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()) { |