Commit 0615bff0 authored by Teng Qin's avatar Teng Qin Committed by 4ast

Fix trace.py USDT argument filtering (#710)

parent 396ecd79
...@@ -40,6 +40,9 @@ void bcc_usdt_foreach(void *usdt, bcc_usdt_cb callback); ...@@ -40,6 +40,9 @@ void bcc_usdt_foreach(void *usdt, bcc_usdt_cb callback);
int bcc_usdt_enable_probe(void *, const char *, const char *); int bcc_usdt_enable_probe(void *, const char *, const char *);
const char *bcc_usdt_genargs(void *); const char *bcc_usdt_genargs(void *);
const char *bcc_usdt_get_probe_argctype(
void *ctx, const char* probe_name, const int arg_index
);
typedef void (*bcc_usdt_uprobe_cb)(const char *, const char *, uint64_t, int); typedef void (*bcc_usdt_uprobe_cb)(const char *, const char *, uint64_t, int);
void bcc_usdt_foreach_uprobe(void *usdt, bcc_usdt_uprobe_cb callback); void bcc_usdt_foreach_uprobe(void *usdt, bcc_usdt_uprobe_cb callback);
......
...@@ -344,6 +344,14 @@ const char *bcc_usdt_genargs(void *usdt) { ...@@ -344,6 +344,14 @@ const char *bcc_usdt_genargs(void *usdt) {
return storage_.c_str(); return storage_.c_str();
} }
const char *bcc_usdt_get_probe_argctype(
void *ctx, const char* probe_name, const int arg_index
) {
USDT::Probe *p = static_cast<USDT::Context *>(ctx)->get(probe_name);
std::string res = p ? p->get_arg_ctype(arg_index) : "";
return res.c_str();
}
void bcc_usdt_foreach(void *usdt, bcc_usdt_cb callback) { void bcc_usdt_foreach(void *usdt, bcc_usdt_cb callback) {
USDT::Context *ctx = static_cast<USDT::Context *>(usdt); USDT::Context *ctx = static_cast<USDT::Context *>(usdt);
ctx->each(callback); ctx->each(callback);
......
...@@ -154,6 +154,9 @@ public: ...@@ -154,6 +154,9 @@ public:
uint64_t address(size_t n = 0) const { return locations_[n].address_; } uint64_t address(size_t n = 0) const { return locations_[n].address_; }
bool usdt_getarg(std::ostream &stream); bool usdt_getarg(std::ostream &stream);
std::string get_arg_ctype(int arg_index) {
return largest_arg_type(arg_index);
}
bool need_enable() const { return semaphore_ != 0x0; } bool need_enable() const { return semaphore_ != 0x0; }
bool enable(const std::string &fn_name); bool enable(const std::string &fn_name);
......
...@@ -157,6 +157,9 @@ lib.bcc_usdt_enable_probe.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p] ...@@ -157,6 +157,9 @@ lib.bcc_usdt_enable_probe.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p]
lib.bcc_usdt_genargs.restype = ct.c_char_p lib.bcc_usdt_genargs.restype = ct.c_char_p
lib.bcc_usdt_genargs.argtypes = [ct.c_void_p] lib.bcc_usdt_genargs.argtypes = [ct.c_void_p]
lib.bcc_usdt_get_probe_argctype.restype = ct.c_char_p
lib.bcc_usdt_get_probe_argctype.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_int]
class bcc_usdt(ct.Structure): class bcc_usdt(ct.Structure):
_fields_ = [ _fields_ = [
('provider', ct.c_char_p), ('provider', ct.c_char_p),
......
...@@ -55,6 +55,10 @@ class USDT(object): ...@@ -55,6 +55,10 @@ class USDT(object):
def get_text(self): def get_text(self):
return lib.bcc_usdt_genargs(self.context) return lib.bcc_usdt_genargs(self.context)
def get_probe_arg_ctype(self, probe_name, arg_index):
return lib.bcc_usdt_get_probe_argctype(
self.context, probe_name, arg_index)
def enumerate_probes(self): def enumerate_probes(self):
probes = [] probes = []
def _add_probe(probe): def _add_probe(probe):
......
...@@ -299,6 +299,26 @@ BPF_PERF_OUTPUT(%s); ...@@ -299,6 +299,26 @@ BPF_PERF_OUTPUT(%s);
(idx, Probe.c_type[field_type], expr) (idx, Probe.c_type[field_type], expr)
self._bail("unrecognized field type %s" % field_type) self._bail("unrecognized field type %s" % field_type)
def _generate_usdt_filter_read(self):
text = ""
if self.probe_type == "u":
for arg, _ in Probe.aliases.items():
if not (arg.startswith("arg") and (arg in self.filter)):
continue
arg_index = int(arg.replace("arg", ""))
arg_ctype = self.usdt.get_probe_arg_ctype(
self.usdt_name, arg_index)
if not arg_ctype:
self._bail("Unable to determine type of {} "
"in the filter".format(arg))
text += """
{} {}_filter;
bpf_usdt_readarg({}, ctx, &{}_filter);
""".format(arg_ctype, arg, arg_index, arg)
self.filter = self.filter.replace(
arg, "{}_filter".format(arg))
return text
def generate_program(self, include_self): def generate_program(self, include_self):
data_decl = self._generate_data_decl() data_decl = self._generate_data_decl()
# kprobes don't have built-in pid filters, so we have to add # kprobes don't have built-in pid filters, so we have to add
...@@ -329,6 +349,7 @@ BPF_PERF_OUTPUT(%s); ...@@ -329,6 +349,7 @@ BPF_PERF_OUTPUT(%s);
text = """ text = """
int %s(%s) int %s(%s)
{ {
%s
%s %s
%s %s
if (!(%s)) return 0; if (!(%s)) return 0;
...@@ -343,7 +364,8 @@ int %s(%s) ...@@ -343,7 +364,8 @@ int %s(%s)
} }
""" """
text = text % (self.probe_name, signature, text = text % (self.probe_name, signature,
pid_filter, prefix, self.filter, pid_filter, prefix,
self._generate_usdt_filter_read(), self.filter,
self.struct_name, data_fields, self.events_name) self.struct_name, data_fields, self.events_name)
return data_decl + "\n" + text return data_decl + "\n" + text
......
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