Commit 163a73fa authored by Sasha Goldshtein's avatar Sasha Goldshtein Committed by 4ast

cc: Support glob+offset format in USDT arguments (#753)

Modern versions of USDT probes (such as what's found in
PostgreSQL when compiled with `--enable-dtrace`) may have
the offset listed after the global symbol for USDT
arguments of the format `4@symbol+8(%rip)`. This commit
extends the argument parser to support these cases, adds
tests for these cases, and makes sure that in case of a
parse error, the parser always moves forward and consumes
at least one character. Presently, the parser would get
stuck on the problematic position and enter an infinite
loop.
parent 6ac44b5a
......@@ -146,6 +146,9 @@ ssize_t ArgumentParser::parse_expr(ssize_t pos, Argument *dest) {
} else {
dest->deref_offset_ = 0;
pos = parse_identifier(pos, &dest->deref_ident_);
if (arg_[pos] == '+' || arg_[pos] == '-') {
pos = parse_number(pos, &dest->deref_offset_);
}
}
if (arg_[pos] != '(')
......@@ -184,10 +187,12 @@ bool ArgumentParser::parse(Argument *dest) {
ssize_t res = parse_1(cur_pos_, dest);
if (res < 0) {
print_error(-res);
cur_pos_ = -res;
return false;
}
if (!isspace(arg_[res]) && arg_[res] != '\0') {
print_error(res);
cur_pos_ = res;
return false;
}
while (isspace(arg_[res])) res++;
......
......@@ -48,12 +48,25 @@ static void verify_register(USDT::ArgumentParser_x64 &parser, int arg_size,
}
TEST_CASE("test usdt argument parsing", "[usdt]") {
SECTION("parse failure") {
USDT::ArgumentParser_x64 parser("4@i%ra+1r");
USDT::Argument arg;
REQUIRE(!parser.parse(&arg));
int i;
for (i = 0; i < 10 && !parser.done(); ++i) {
parser.parse(&arg);
}
// Make sure we reach termination
REQUIRE(i < 10);
}
SECTION("argument examples from the Python implementation") {
USDT::ArgumentParser_x64 parser(
"-4@$0 8@$1234 %rdi %rax %rsi "
"-8@%rbx 4@%r12 8@-8(%rbp) 4@(%rax) "
"-4@global_max_action(%rip) "
"8@24+mp_(%rip) ");
"8@24+mp_(%rip) "
"-4@CheckpointStats+40(%rip) "
"4@glob-2(%rip) ");
verify_register(parser, -4, 0);
verify_register(parser, 8, 1234);
......@@ -69,6 +82,8 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
verify_register(parser, -4, "ip", 0, std::string("global_max_action"));
verify_register(parser, 8, "ip", 24, std::string("mp_"));
verify_register(parser, -4, "ip", 40, std::string("CheckpointStats"));
verify_register(parser, 4, "ip", -2, std::string("glob"));
REQUIRE(parser.done());
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment