summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2015-05-05 19:58:07 -0700
committerYabin Cui <yabinc@google.com>2015-05-13 16:16:56 -0700
commit8f6225147c5b6cb2159a7f5cb0dab952ee0759df (patch)
treebfc1ba2394275e2ea87cf2d4ceae09d5323d5a23 /simpleperf/cmd_record.cpp
parent884fc856c79eddf8ac68fd54d75d804116f577e5 (diff)
downloadextras-8f6225147c5b6cb2159a7f5cb0dab952ee0759df.tar.gz
Dump build_id feature in `simpleperf record`.
Bug: 19483574 Change-Id: Ie2acd8a157bca9ad3c01a2e4b37e139aba89670f
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r--simpleperf/cmd_record.cpp63
1 files changed, 62 insertions, 1 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index e27b6e4b..98a0cd55 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -14,17 +14,20 @@
* limitations under the License.
*/
+#include <libgen.h>
#include <poll.h>
#include <signal.h>
#include <string>
#include <vector>
#include <base/logging.h>
+#include <base/strings.h>
#include "command.h"
#include "environment.h"
#include "event_selection_set.h"
#include "event_type.h"
+#include "read_elf.h"
#include "record.h"
#include "record_file.h"
#include "utils.h"
@@ -60,6 +63,8 @@ class RecordCommandImpl {
bool WriteData(const char* data, size_t size);
bool DumpKernelAndModuleMmaps();
bool DumpThreadCommAndMmaps();
+ bool DumpAdditionalFeatures();
+ bool DumpBuildIdFeature();
bool use_sample_freq_; // Use sample_freq_ when true, otherwise using sample_period_.
uint64_t sample_freq_; // Sample 'sample_freq_' times per second.
@@ -157,7 +162,10 @@ bool RecordCommandImpl::Run(const std::vector<std::string>& args) {
poll(&pollfds[0], pollfds.size(), -1);
}
- // 6. Close record file.
+ // 6. Dump additional features, and close record file.
+ if (!DumpAdditionalFeatures()) {
+ return false;
+ }
if (!record_file_writer_->Close()) {
return false;
}
@@ -302,6 +310,59 @@ bool RecordCommandImpl::DumpThreadCommAndMmaps() {
return true;
}
+bool RecordCommandImpl::DumpAdditionalFeatures() {
+ if (!record_file_writer_->WriteFeatureHeader(1)) {
+ return false;
+ }
+ return DumpBuildIdFeature();
+}
+
+bool RecordCommandImpl::DumpBuildIdFeature() {
+ std::vector<std::string> hit_kernel_modules;
+ std::vector<std::string> hit_user_files;
+ if (!record_file_writer_->GetHitModules(&hit_kernel_modules, &hit_user_files)) {
+ return false;
+ }
+ std::vector<BuildIdRecord> build_id_records;
+ BuildId build_id;
+ // Add build_ids for kernel/modules.
+ for (auto& filename : hit_kernel_modules) {
+ if (filename == DEFAULT_KERNEL_MMAP_NAME) {
+ if (!GetKernelBuildId(&build_id)) {
+ LOG(DEBUG) << "can't read build_id for kernel";
+ continue;
+ }
+ build_id_records.push_back(
+ CreateBuildIdRecord(true, UINT_MAX, build_id, DEFAULT_KERNEL_FILENAME_FOR_BUILD_ID));
+ } else {
+ std::string module_name = basename(&filename[0]);
+ if (android::base::EndsWith(module_name, ".ko")) {
+ module_name = module_name.substr(0, module_name.size() - 3);
+ }
+ if (!GetModuleBuildId(module_name, &build_id)) {
+ LOG(DEBUG) << "can't read build_id for module " << module_name;
+ continue;
+ }
+ build_id_records.push_back(CreateBuildIdRecord(true, UINT_MAX, build_id, filename));
+ }
+ }
+ // Add build_ids for user elf files.
+ for (auto& filename : hit_user_files) {
+ if (filename == DEFAULT_EXECNAME_FOR_THREAD_MMAP) {
+ continue;
+ }
+ if (!GetBuildIdFromElfFile(filename, &build_id)) {
+ LOG(DEBUG) << "can't read build_id from file " << filename;
+ continue;
+ }
+ build_id_records.push_back(CreateBuildIdRecord(false, UINT_MAX, build_id, filename));
+ }
+ if (!record_file_writer_->WriteBuildIdFeature(build_id_records)) {
+ return false;
+ }
+ return true;
+}
+
class RecordCommand : public Command {
public:
RecordCommand()