Skip to content

Commit

Permalink
trace, argdist: Treat small USDT arguments correctly
Browse files Browse the repository at this point in the history
trace and argdist currently only work correctly for USDT arguments
whose size is exactly 8 bytes. Smaller types, such as chars, shorts,
ints (signed or unsigned) are not treated correctly. The reason is
that the produced program would invoke the `bpf_usdt_readarg` helper
with the address of a u64 local variable, and then cast that variable
to the user-specified type derived from the format string. However,
the `bpf_usdt_readarg` rewriting then passes `sizeof(u64)` to the
generated `bpf_..._readarg` macro, which then fails to read anything
because the provided size doesn't match the argument size it knows
about.

The fix is fairly easy: instead of declaring a u64 unconditionally
and reading into that variable with `bpf_usdt_readarg`, declare a
variable that has the correct type according to what we know about
the USDT probe.
  • Loading branch information
goldshtn committed Feb 20, 2017
1 parent 203fd27 commit 3a5256f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
7 changes: 5 additions & 2 deletions tools/argdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,12 @@ def _generate_hash_field(self, i):
def _generate_usdt_arg_assignment(self, i):
expr = self.exprs[i]
if self.probe_type == "u" and expr[0:3] == "arg":
return (" u64 %s = 0;\n" +
arg_index = int(expr[3])
arg_ctype = self.usdt_ctx.get_probe_arg_ctype(
self.function, arg_index - 1)
return (" %s %s = 0;\n" +
" bpf_usdt_readarg(%s, ctx, &%s);\n") \
% (expr, expr[3], expr)
% (arg_ctype, expr, expr[3], expr)
else:
return ""

Expand Down
7 changes: 5 additions & 2 deletions tools/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,12 @@ def _generate_field_assign(self, idx):
expr = self.values[idx].strip()
text = ""
if self.probe_type == "u" and expr[0:3] == "arg":
text = (" u64 %s = 0;\n" +
arg_index = int(expr[3])
arg_ctype = self.usdt.get_probe_arg_ctype(
self.usdt_name, arg_index - 1)
text = (" %s %s = 0;\n" +
" bpf_usdt_readarg(%s, ctx, &%s);\n") \
% (expr, expr[3], expr)
% (arg_ctype, expr, expr[3], expr)

if field_type == "s":
return text + """
Expand Down

0 comments on commit 3a5256f

Please sign in to comment.