From 9562285c70c6216961ce239c261cdd08fc54e3d5 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Thu, 17 Dec 2020 14:52:30 -0800 Subject: 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 --- simpleperf/cmd_record.cpp | 105 ++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 35 deletions(-) (limited to 'simpleperf/cmd_record.cpp') 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* filters) { - std::vector args = android::base::Split(s, " -@"); - std::unique_ptr elf; + std::vector 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 || stop - 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 @ || stop @ - 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 + filters->emplace_back(AddrFilter::KERNEL_START, addr1, 0, ""); + return true; } - } else if (args[0] == "filter") { - if (args.size() == 2) { - // filter - 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 @ + 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 - - filters->emplace_back(AddrFilter::KERNEL_RANGE, addr1, addr2 - addr1, ""); + } + } + if (auto p = s.data(); ConsumeStr(p, "stop") && ConsumeAddr(p, &addr1)) { + if (*p == '\0') { + // stop + filters->emplace_back(AddrFilter::KERNEL_STOP, addr1, 0, ""); + return true; + } + if (ConsumeStr(p, "@") && *p != '\0') { + // stop @ + 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 -@ + } + } + if (auto p = s.data(); ConsumeStr(p, "filter") && ConsumeAddr(p, &addr1) && ConsumeStr(p, "-") && + ConsumeAddr(p, &addr2)) { + if (*p == '\0') { + // filter - + filters->emplace_back(AddrFilter::KERNEL_RANGE, addr1, addr2 - addr1, ""); + return true; + } + if (ConsumeStr(p, "@") && *p != '\0') { + // filter -@ + 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 + 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; } -- cgit v1.2.3