summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2020-12-17 14:52:30 -0800
committerYabin Cui <yabinc@google.com>2020-12-17 14:56:09 -0800
commit9562285c70c6216961ce239c261cdd08fc54e3d5 (patch)
treee55ceae0df7fd80818c04152044f09dcd6eb66b4 /simpleperf/cmd_record.cpp
parentcaabdfb51de6c152ef6e2ef1d698d4c704e04c39 (diff)
downloadextras-9562285c70c6216961ce239c261cdd08fc54e3d5.tar.gz
simpleperf: fix unit test on linux host.
Fix failed tests: record_cmd.tp_filter_option record_cmd.ParseAddrFilterOption Bug: 175885920 Test: run simpleperf_unit_test Change-Id: I99f30e6a88f25cd4ca74be30256eb71760a5c47f
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r--simpleperf/cmd_record.cpp105
1 files changed, 70 insertions, 35 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index b4d9328a..60677a7c 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -1887,59 +1887,94 @@ void RecordCommand::CollectHitFileInfo(const SampleRecord& r) {
namespace simpleperf {
+static bool ConsumeStr(const char*& p, const char* s) {
+ if (strncmp(p, s, strlen(s)) == 0) {
+ p += strlen(s);
+ return true;
+ }
+ return false;
+}
+
+static bool ConsumeAddr(const char*& p, uint64_t* addr) {
+ errno = 0;
+ char* end;
+ *addr = strtoull(p, &end, 0);
+ if (errno == 0 && p != end) {
+ p = end;
+ return true;
+ }
+ return false;
+}
+
// To reduce function length, not all format errors are checked.
static bool ParseOneAddrFilter(const std::string& s, std::vector<AddrFilter>* filters) {
- std::vector<std::string> args = android::base::Split(s, " -@");
- std::unique_ptr<ElfFile> elf;
+ std::vector<std::string> args = android::base::Split(s, " ");
+ if (args.size() != 2) {
+ return false;
+ }
+
uint64_t addr1;
uint64_t addr2;
uint64_t off1;
uint64_t off2;
std::string path;
- if (args[0] == "start" || args[0] == "stop") {
- if (args.size() >= 2 && ParseUint(args[1], &addr1)) {
- if (args.size() == 2) {
- // start <kernel_addr> || stop <kernel_addr>
- filters->emplace_back(
- args[0] == "start" ? AddrFilter::KERNEL_START : AddrFilter::KERNEL_STOP, addr1, 0, "");
- return true;
- }
- if (auto elf = ElfFile::Open(args[2]);
- elf && elf->VaddrToOff(addr1, &off1) && Realpath(args[2], &path)) {
- // start <vaddr>@<file_path> || stop <vaddr>@<file_path>
- filters->emplace_back(args[0] == "start" ? AddrFilter::FILE_START : AddrFilter::FILE_STOP,
- off1, 0, path);
- return true;
- }
+ if (auto p = s.data(); ConsumeStr(p, "start") && ConsumeAddr(p, &addr1)) {
+ if (*p == '\0') {
+ // start <kernel_addr>
+ filters->emplace_back(AddrFilter::KERNEL_START, addr1, 0, "");
+ return true;
}
- } else if (args[0] == "filter") {
- if (args.size() == 2) {
- // filter <file_path>
- if (auto elf = ElfFile::Open(args[1]); elf) {
- for (const ElfSegment& seg : elf->GetProgramHeader()) {
- if (seg.is_executable) {
- filters->emplace_back(AddrFilter::FILE_RANGE, seg.file_offset, seg.file_size, args[1]);
- }
- }
+ if (ConsumeStr(p, "@") && *p != '\0') {
+ // start <vaddr>@<file_path>
+ if (auto elf = ElfFile::Open(p); elf && elf->VaddrToOff(addr1, &off1) && Realpath(p, &path)) {
+ filters->emplace_back(AddrFilter::FILE_START, off1, 0, path);
return true;
}
- } else if (args.size() >= 3 && ParseUint(args[1], &addr1) && ParseUint(args[2], &addr2) &&
- addr1 < addr2) {
- if (args.size() == 3) {
- // filter <kernel_addr_start>-<kernel_addr_end>
- filters->emplace_back(AddrFilter::KERNEL_RANGE, addr1, addr2 - addr1, "");
+ }
+ }
+ if (auto p = s.data(); ConsumeStr(p, "stop") && ConsumeAddr(p, &addr1)) {
+ if (*p == '\0') {
+ // stop <kernel_addr>
+ filters->emplace_back(AddrFilter::KERNEL_STOP, addr1, 0, "");
+ return true;
+ }
+ if (ConsumeStr(p, "@") && *p != '\0') {
+ // stop <vaddr>@<file_path>
+ if (auto elf = ElfFile::Open(p); elf && elf->VaddrToOff(addr1, &off1) && Realpath(p, &path)) {
+ filters->emplace_back(AddrFilter::FILE_STOP, off1, 0, path);
return true;
}
- if (auto elf = ElfFile::Open(args[3]); elf && elf->VaddrToOff(addr1, &off1) &&
- elf->VaddrToOff(addr2, &off2) &&
- Realpath(args[3], &path)) {
- // filter <vaddr_start>-<vaddr_end>@<file_path>
+ }
+ }
+ if (auto p = s.data(); ConsumeStr(p, "filter") && ConsumeAddr(p, &addr1) && ConsumeStr(p, "-") &&
+ ConsumeAddr(p, &addr2)) {
+ if (*p == '\0') {
+ // filter <kernel_addr_start>-<kernel_addr_end>
+ filters->emplace_back(AddrFilter::KERNEL_RANGE, addr1, addr2 - addr1, "");
+ return true;
+ }
+ if (ConsumeStr(p, "@") && *p != '\0') {
+ // filter <vaddr_start>-<vaddr_end>@<file_path>
+ if (auto elf = ElfFile::Open(p); elf && elf->VaddrToOff(addr1, &off1) &&
+ elf->VaddrToOff(addr2, &off2) && Realpath(p, &path)) {
filters->emplace_back(AddrFilter::FILE_RANGE, off1, off2 - off1, path);
return true;
}
}
}
+ if (auto p = s.data(); ConsumeStr(p, "filter") && *p != '\0') {
+ // filter <file_path>
+ path = android::base::Trim(p);
+ if (auto elf = ElfFile::Open(path); elf) {
+ for (const ElfSegment& seg : elf->GetProgramHeader()) {
+ if (seg.is_executable) {
+ filters->emplace_back(AddrFilter::FILE_RANGE, seg.file_offset, seg.file_size, path);
+ }
+ }
+ return true;
+ }
+ }
return false;
}