diff options
author | Yabin Cui <yabinc@google.com> | 2015-05-04 20:27:57 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2015-05-05 14:23:10 -0700 |
commit | 7d59bb49fb47fbc82ef5c77d7aebf7174fd996e1 (patch) | |
tree | 8c090275f1d8f88edb80b8f7746751256e1538ba /simpleperf/cmd_record.cpp | |
parent | 1352b82d4aed6b5dd64cffaa2aefec0cfd45aeaa (diff) | |
download | extras-7d59bb49fb47fbc82ef5c77d7aebf7174fd996e1.tar.gz |
Dump kernel/modules/thread mmap information in `simpleperf record`.
Bug: 19483574
Change-Id: Ia65cb12804a6dffa440501736a6229b2f7248958
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r-- | simpleperf/cmd_record.cpp | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp index e835acd6..e27b6e4b 100644 --- a/simpleperf/cmd_record.cpp +++ b/simpleperf/cmd_record.cpp @@ -25,6 +25,7 @@ #include "environment.h" #include "event_selection_set.h" #include "event_type.h" +#include "record.h" #include "record_file.h" #include "utils.h" #include "workload.h" @@ -57,6 +58,8 @@ class RecordCommandImpl { bool SetMeasuredEventType(const std::string& event_type_name); void SetEventSelection(); bool WriteData(const char* data, size_t size); + bool DumpKernelAndModuleMmaps(); + bool DumpThreadCommAndMmaps(); bool use_sample_freq_; // Use sample_freq_ when true, otherwise using sample_period_. uint64_t sample_freq_; // Sample 'sample_freq_' times per second. @@ -116,15 +119,21 @@ bool RecordCommandImpl::Run(const std::vector<std::string>& args) { std::vector<pollfd> pollfds; event_selection_set_.PreparePollForEventFiles(&pollfds); - // 4. Open record file writer. + // 4. Open record file writer, and dump kernel/modules/threads mmap information. record_file_writer_ = RecordFileWriter::CreateInstance( record_filename_, event_selection_set_.FindEventAttrByType(*measured_event_type_), event_selection_set_.FindEventFdsByType(*measured_event_type_)); if (record_file_writer_ == nullptr) { return false; } + if (!DumpKernelAndModuleMmaps()) { + return false; + } + if (system_wide_collection_ && !DumpThreadCommAndMmaps()) { + return false; + } - // 5. Dump records in mmap buffers of perf_event_files to output file while workload is running. + // 5. Write records in mmap buffers of perf_event_files to output file while workload is running. // If monitoring only one process, we use the enable_on_exec flag, and don't need to start // recording manually. @@ -234,6 +243,65 @@ bool RecordCommandImpl::WriteData(const char* data, size_t size) { return record_file_writer_->WriteData(data, size); } +bool RecordCommandImpl::DumpKernelAndModuleMmaps() { + KernelMmap kernel_mmap; + std::vector<ModuleMmap> module_mmaps; + if (!GetKernelAndModuleMmaps(&kernel_mmap, &module_mmaps)) { + return false; + } + const perf_event_attr& attr = event_selection_set_.FindEventAttrByType(*measured_event_type_); + MmapRecord mmap_record = CreateMmapRecord(attr, true, UINT_MAX, 0, kernel_mmap.start_addr, + kernel_mmap.len, kernel_mmap.pgoff, kernel_mmap.name); + if (!record_file_writer_->WriteData(mmap_record.BinaryFormat())) { + return false; + } + for (auto& module_mmap : module_mmaps) { + std::string filename = module_mmap.filepath; + if (filename.empty()) { + filename = "[" + module_mmap.name + "]"; + } + MmapRecord mmap_record = CreateMmapRecord(attr, true, UINT_MAX, 0, module_mmap.start_addr, + module_mmap.len, 0, filename); + if (!record_file_writer_->WriteData(mmap_record.BinaryFormat())) { + return false; + } + } + return true; +} + +bool RecordCommandImpl::DumpThreadCommAndMmaps() { + std::vector<ThreadComm> thread_comms; + if (!GetThreadComms(&thread_comms)) { + return false; + } + const perf_event_attr& attr = event_selection_set_.FindEventAttrByType(*measured_event_type_); + for (auto& thread : thread_comms) { + CommRecord record = CreateCommRecord(attr, thread.tgid, thread.tid, thread.comm); + if (!record_file_writer_->WriteData(record.BinaryFormat())) { + return false; + } + if (thread.is_process) { + std::vector<ThreadMmap> thread_mmaps; + if (!GetThreadMmapsInProcess(thread.tgid, &thread_mmaps)) { + // The thread may exit before we get its info. + continue; + } + for (auto& thread_mmap : thread_mmaps) { + if (thread_mmap.executable == 0) { + continue; // No need to dump non-executable mmap info. + } + MmapRecord record = + CreateMmapRecord(attr, false, thread.tgid, thread.tid, thread_mmap.start_addr, + thread_mmap.len, thread_mmap.pgoff, thread_mmap.name); + if (!record_file_writer_->WriteData(record.BinaryFormat())) { + return false; + } + } + } + } + return true; +} + class RecordCommand : public Command { public: RecordCommand() |