Commit 510b2cea authored by Alastair Robertson's avatar Alastair Robertson

Support attaching probes to multiple functions

e.g.: kprobe:sys_read,sys_write { @[func] = count() }
parent 0e82af01
......@@ -93,5 +93,18 @@ std::string opstr(Unop &unop)
}
}
std::string Probe::name() const
{
std::string n = type;
if (path != "")
n += ":" + path;
n += ":";
for (std::string attach_point : *attach_points)
{
n += attach_point + ",";
}
return n.substr(0, n.size()-1);
}
} // namespace ast
} // namespace bpftrace
......@@ -135,27 +135,26 @@ public:
void accept(Visitor &v) override;
};
using AttachPointList = std::vector<std::string>;
class Probe : public Node {
public:
Probe(const std::string &type, Predicate *pred, StatementList *stmts)
: type(type), name(type), pred(pred), stmts(stmts) { }
Probe(const std::string &type, const std::string &attach_point,
: type(type), attach_points(new AttachPointList), pred(pred), stmts(stmts) { }
Probe(const std::string &type, AttachPointList *attach_points,
Predicate *pred, StatementList *stmts)
: type(type), attach_point(attach_point), name(type+":"+attach_point),
pred(pred), stmts(stmts) { }
: type(type), attach_points(attach_points), pred(pred), stmts(stmts) { }
Probe(const std::string &type, const std::string &path,
const std::string &attach_point, Predicate *pred, StatementList *stmts)
: type(type), path(path), attach_point(attach_point),
name(type+":"+path+":"+attach_point), pred(pred), stmts(stmts) { }
AttachPointList *attach_points, Predicate *pred, StatementList *stmts)
: type(type), path(path), attach_points(attach_points), pred(pred), stmts(stmts) { }
std::string type;
std::string path;
std::string attach_point;
std::string name;
AttachPointList *attach_points;
Predicate *pred;
StatementList *stmts;
void accept(Visitor &v) override;
std::string name() const;
};
using ProbeList = std::vector<Probe *>;
......
......@@ -15,28 +15,36 @@ namespace bpftrace {
int BPFtrace::add_probe(ast::Probe &p)
{
Probe probe;
probe.path = p.path;
probe.attach_point = p.attach_point;
probe.name = p.name;
probe.type = probetype(p.type);
if (p.type == "BEGIN")
{
Probe probe;
probe.path = bpftrace_path_;
probe.attach_point = "BEGIN_trigger";
probe.type = probetype(p.type);
probe.name = p.name();
special_probes_.push_back(probe);
return 0;
}
else if (p.type == "END")
{
Probe probe;
probe.path = bpftrace_path_;
probe.attach_point = "END_trigger";
probe.type = probetype(p.type);
probe.name = p.name();
special_probes_.push_back(probe);
return 0;
}
probes_.push_back(probe);
for (std::string attach_point : *p.attach_points)
{
Probe probe;
probe.path = p.path;
probe.attach_point = attach_point;
probe.type = probetype(p.type);
probe.name = p.name();
probes_.push_back(probe);
}
return 0;
}
......
......@@ -334,8 +334,8 @@ void CodegenLLVM::visit(Probe &probe)
b_.getInt64Ty(),
{b_.getInt8PtrTy()}, // struct pt_regs *ctx
false);
Function *func = Function::Create(func_type, Function::ExternalLinkage, probe.name, module_.get());
func->setSection(probe.name);
Function *func = Function::Create(func_type, Function::ExternalLinkage, probe.name(), module_.get());
func->setSection(probe.name());
BasicBlock *entry = BasicBlock::Create(module_->getContext(), "entry", func);
b_.SetInsertPoint(entry);
......
......@@ -84,6 +84,7 @@ void yyerror(bpftrace::Driver &driver, const char *s);
%type <ast::Map *> map
%type <ast::Variable *> var
%type <ast::ExpressionList *> vargs
%type <ast::AttachPointList *> attach_points
%right ASSIGN
%left LOR
......@@ -108,11 +109,15 @@ probes : probes probe { $$ = $1; $1->push_back($2); }
| probe { $$ = new ast::ProbeList; $$->push_back($1); }
;
probe : IDENT pred block { $$ = new ast::Probe($1, $2, $3); }
| IDENT ":" IDENT pred block { $$ = new ast::Probe($1, $3, $4, $5); }
| IDENT PATH IDENT pred block { $$ = new ast::Probe($1, $2.substr(1, $2.size()-2), $3, $4, $5); }
probe : IDENT pred block { $$ = new ast::Probe($1, $2, $3); }
| IDENT ":" attach_points pred block { $$ = new ast::Probe($1, $3, $4, $5); }
| IDENT PATH attach_points pred block { $$ = new ast::Probe($1, $2.substr(1, $2.size()-2), $3, $4, $5); }
;
attach_points : attach_points "," IDENT { $$ = $1; $1->push_back($3); }
| IDENT { $$ = new ast::AttachPointList; $$->push_back($1); }
;
pred : DIV expr ENDPRED { $$ = new ast::Predicate($2); }
| { $$ = nullptr; }
......
......@@ -126,7 +126,7 @@ void Printer::visit(Predicate &pred)
void Printer::visit(Probe &probe)
{
std::string indent(depth_, ' ');
out_ << indent << probe.name << std::endl;
out_ << indent << probe.name() << std::endl;
++depth_;
if (probe.pred) {
......
......@@ -322,19 +322,19 @@ void SemanticAnalyser::visit(Probe &probe)
probe_ = &probe;
if (probe.type == "kprobe" || probe.type == "kretprobe") {
if (probe.attach_point == "")
if (probe.attach_points->size() == 0)
err_ << "kprobes must have an attachment point" << std::endl;
if (probe.path != "")
err_ << "kprobes should not have a path" << std::endl;
}
else if (probe.type == "uprobe" || probe.type == "uretprobe") {
if (probe.attach_point == "")
if (probe.attach_points->size() == 0)
err_ << "uprobes must have an attachment point" << std::endl;
if (probe.path == "")
err_ << "uprobes must have a path" << std::endl;
}
else if (probe.type == "BEGIN" || probe.type == "END") {
if (probe.attach_point != "")
if (probe.attach_points->size() != 0)
err_ << "BEGIN/END probes should not have an attachment point" << std::endl;
if (probe.path != "")
err_ << "BEGIN/END probes should not have a path" << std::endl;
......
......@@ -220,6 +220,14 @@ TEST(Parser, begin_probe)
" int: 1\n");
}
TEST(Parser, multiple_attach_points)
{
test("kprobe:sys_open,sys_close { 1 }",
"Program\n"
" kprobe:sys_open,sys_close\n"
" int: 1\n");
}
} // namespace parser
} // namespace test
} // namespace bpftrace
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