From 9c7f9e5fbcd1eeb90b89d2db5b41fca76e952c4f Mon Sep 17 00:00:00 2001 From: Matheus Marchini Date: Wed, 17 Apr 2019 17:57:07 -0700 Subject: [PATCH] improve probes lookup by dropping use of regex Ref: https://github.com/iovisor/bpftrace/issues/526 --- src/bpftrace.cpp | 65 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/src/bpftrace.cpp b/src/bpftrace.cpp index 9098dddf59fe..0b062aac668d 100644 --- a/src/bpftrace.cpp +++ b/src/bpftrace.cpp @@ -145,25 +145,64 @@ int BPFtrace::add_probe(ast::Probe &p) std::set BPFtrace::find_wildcard_matches(const std::string &prefix, const std::string &func, std::istream &symbol_name_stream) { - // Turn glob into a regex - auto regex_str = "(" + std::regex_replace(func, std::regex("\\*"), "[^\\s]*") + ")"; - if (prefix != "") - regex_str = prefix + ":" + regex_str; - regex_str = "^" + regex_str; - std::regex func_regex(regex_str); - std::smatch match; + bool start_wildcard = func[0] == '*'; + bool end_wildcard = func[func.length() - 1] == '*'; + + // TODO(mmarchini): turn this into a helper function. Add tests + std::vector tokens; + size_t next = start_wildcard ? 1 : 0; + size_t end = func.length(); + while (next < end) { + size_t found = func.find('*', next); + std::string token; + if (found == end) { + token = func.substr(next, end - next); + next = end; + } else if (found == std::string::npos) { + token = func.substr(next, end - next); + next = end; + } else { + token = func.substr(next, found - next); + next = found + 1; + } + tokens.push_back(token); + } std::string line; std::set matches; while (std::getline(symbol_name_stream, line)) { - if (std::regex_search(line, match, func_regex)) - { - assert(match.size() == 2); - // skip the ".part.N" kprobe variants, as they can't be traced: - if (std::strstr(match.str(1).c_str(), ".part.") == NULL) - matches.insert(match[1]); + size_t next = 0; + if (!prefix.empty()) { + if (line.find(prefix, next) != std::string::npos) + continue; + next += prefix.length(); + } + + if (!start_wildcard) + if (line.find(tokens[0], next) != next) + continue; + + bool cool = true; + for (std::string token : tokens) { + size_t found = line.find(token, next); + if (found == std::string::npos) { + cool = false; + break; + } + + next = found + token.length(); } + if (!cool) continue; + + if (!end_wildcard) + if (line.length() != next) + continue; + + if (line.find(".part.") != std::string::npos) + continue; + + matches.insert(line); } return matches; }