summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-03-20 19:22:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-03-20 19:22:24 +0000
commitdd4f07b1396db2b95d9dddad03b743eaca462c53 (patch)
tree5f2557a3e79cef474ec476d28391e69efd3f8d1d /simpleperf/cmd_record.cpp
parent5626a71ff0edc0ff7d6420f35fb18c70e6644201 (diff)
parent9e43e9fabd1e4b2b6f5d58de1ad1edfd3c9feb7e (diff)
downloadextras-dd4f07b1396db2b95d9dddad03b743eaca462c53.tar.gz
Merge "simpleperf: Add JITDebugReader."
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r--simpleperf/cmd_record.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index bb659c7f..35d0f939 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -42,6 +42,7 @@
#include "event_selection_set.h"
#include "event_type.h"
#include "IOEventLoop.h"
+#include "JITDebugReader.h"
#include "OfflineUnwinder.h"
#include "perf_clock.h"
#include "read_apk.h"
@@ -253,6 +254,7 @@ class RecordCommand : public Command {
bool SaveRecordForPostUnwinding(Record* record);
bool SaveRecordAfterUnwinding(Record* record);
bool SaveRecordWithoutUnwinding(Record* record);
+ bool UpdateJITDebugInfo();
void UpdateRecordForEmbeddedElfPath(Record* record);
bool UnwindRecord(SampleRecord& r);
@@ -301,6 +303,8 @@ class RecordCommand : public Command {
bool allow_callchain_joiner_;
size_t callchain_joiner_min_matching_nodes_;
std::unique_ptr<CallChainJoiner> callchain_joiner_;
+
+ std::unique_ptr<JITDebugReader> jit_debug_reader_;
};
bool RecordCommand::Run(const std::vector<std::string>& args) {
@@ -377,6 +381,7 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
// 4. Add monitored targets.
bool need_to_check_targets = false;
+ pid_t app_pid = 0;
if (system_wide_collection_) {
event_selection_set_.AddMonitoredThreads({-1});
} else if (!event_selection_set_.HasMonitoredTarget()) {
@@ -396,6 +401,10 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
std::set<pid_t> pids = WaitForAppProcesses(app_package_name_);
event_selection_set_.AddMonitoredProcesses(pids);
need_to_check_targets = true;
+ if (!pids.empty()) {
+ // TODO: support a JITDebugReader for each app process?
+ app_pid = *pids.begin();
+ }
} else {
LOG(ERROR)
<< "No threads to monitor. Try `simpleperf help record` for help";
@@ -447,6 +456,21 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
return false;
}
}
+ // Profiling JITed/interpreted code is supported starting from Android P.
+ if (app_pid != 0 && GetAndroidVersion() >= 9) {
+ // JIT symfiles are stored in temporary files, and are deleted after recording. But if
+ // `-g --no-unwind` option is used, we want to keep symfiles to support unwinding in
+ // the debug-unwind cmd.
+ bool keep_symfiles = dwarf_callchain_sampling_ && !unwind_dwarf_callchain_;
+ jit_debug_reader_.reset(new JITDebugReader(app_pid, keep_symfiles));
+ // Update JIT info at the beginning of recording.
+ if (!UpdateJITDebugInfo()) {
+ return false;
+ }
+ if (!loop->AddPeriodicEvent(SecondToTimeval(0.1), [&]() { return UpdateJITDebugInfo(); })) {
+ return false;
+ }
+ }
return true;
}
@@ -1077,6 +1101,14 @@ bool RecordCommand::SaveRecordWithoutUnwinding(Record* record) {
return record_file_writer_->WriteRecord(*record);
}
+bool RecordCommand::UpdateJITDebugInfo() {
+ std::vector<JITSymFile> jit_symfiles;
+ std::vector<DexSymFile> dex_symfiles;
+ jit_debug_reader_->ReadUpdate(&jit_symfiles, &dex_symfiles);
+ // TODO: Handle jit/dex symfiles.
+ return true;
+}
+
template <class RecordType>
void UpdateMmapRecordForEmbeddedElfPath(RecordType* record) {
RecordType& r = *record;