diff options
author | Yabin Cui <yabinc@google.com> | 2020-12-17 14:52:30 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2020-12-17 14:56:09 -0800 |
commit | 9562285c70c6216961ce239c261cdd08fc54e3d5 (patch) | |
tree | e55ceae0df7fd80818c04152044f09dcd6eb66b4 /simpleperf/cmd_record.cpp | |
parent | caabdfb51de6c152ef6e2ef1d698d4c704e04c39 (diff) | |
download | extras-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.cpp | 105 |
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; } |