Skip to content

Commit 5ed9903

Browse files
Support accessing up to 255 USDT probe args (bpftrace#4118)
Support arg0-arg255 for usdt Signed-off-by: gray <greyschwinger@gmail.com>
1 parent 41d1974 commit 5ed9903

File tree

7 files changed

+67
-16
lines changed

7 files changed

+67
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ and this project adheres to
3939
- [#4037](https://github.com/bpftrace/bpftrace/pull/4037)
4040
- Add warning when unset or empty positional parameters are used
4141
- [#4095](https://github.com/bpftrace/bpftrace/pull/4095)
42+
- Support accessing up to 255 USDT probe args
43+
- [#4118](https://github.com/bpftrace/bpftrace/pull/4118)
4244
#### Changed
4345
- `-p` CLI flag now applies to all probes (except BEGIN/END)
4446
- [#3800](https://github.com/bpftrace/bpftrace/pull/3800)

src/ast/ast.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <charconv>
34
#include <cstddef>
45
#include <cstdint>
56
#include <string>
@@ -340,11 +341,24 @@ class Builtin : public Node {
340341
return builtin_type;
341342
}
342343

343-
// Check if the builtin is 'arg0' - 'arg9'
344+
// Check if the builtin is 'arg0' - 'arg255'
344345
bool is_argx() const
345346
{
346-
return !ident.compare(0, 3, "arg") && ident.size() == 4 &&
347-
ident.at(3) >= '0' && ident.at(3) <= '9';
347+
if (ident.size() < 4 || ident.size() > 6 || !ident.starts_with("arg"))
348+
return false;
349+
350+
std::string_view num_part = ident.substr(3);
351+
352+
// no leading zeros
353+
if (num_part.size() > 1 && num_part.front() == '0')
354+
return false;
355+
356+
int arg_num = 0;
357+
auto [ptr, ec] = std::from_chars(num_part.data(),
358+
num_part.data() + num_part.size(),
359+
arg_num);
360+
return ec == std::errc() && ptr == num_part.data() + num_part.size() &&
361+
arg_num >= 0 && arg_num < 256;
348362
}
349363

350364
std::string ident;

src/ast/irbuilderbpf.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "bpftrace.h"
1212
#include "globalvars.h"
1313
#include "log.h"
14+
#include "util/exceptions.h"
1415

1516
namespace libbpf {
1617
#include "libbpf/bpf.h"
@@ -1491,9 +1492,8 @@ Value *IRBuilderBPF::CreateUSDTReadArgument(Value *ctx,
14911492
}
14921493

14931494
if (usdt == nullptr) {
1494-
builtin.addError() << "failed to initialize usdt context for probe "
1495-
<< attach_point->target;
1496-
exit(-1);
1495+
throw util::FatalUserException(
1496+
"failed to initialize usdt context for probe " + attach_point->target);
14971497
}
14981498

14991499
std::string ns = attach_point->usdt.provider;
@@ -1505,10 +1505,10 @@ Value *IRBuilderBPF::CreateUSDTReadArgument(Value *ctx,
15051505
usdt_location_index,
15061506
arg_num,
15071507
&argument) != 0) {
1508-
builtin.addError() << "couldn't get argument " << arg_num << " for "
1509-
<< attach_point->target << ":" << attach_point->ns << ":"
1510-
<< attach_point->func;
1511-
exit(-2);
1508+
throw util::FatalUserException("couldn't get argument " +
1509+
std::to_string(arg_num) + " for " +
1510+
attach_point->target + ":" +
1511+
attach_point->ns + ":" + attach_point->func);
15121512
}
15131513

15141514
Value *result = CreateUSDTReadArgument(ctx, &argument, builtin, as, loc);

src/ast/passes/semantic_analyser.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -950,18 +950,19 @@ void SemanticAnalyser::visit(Builtin &builtin)
950950
return;
951951
ProbeType pt = probetype(probe->attach_points[0]->provider);
952952
AddrSpace addrspace = find_addrspace(pt);
953+
int arg_num = atoi(builtin.ident.substr(3).c_str());
953954
for (auto *attach_point : probe->attach_points) {
954955
ProbeType type = probetype(attach_point->provider);
955956
if (type != ProbeType::kprobe && type != ProbeType::uprobe &&
956957
type != ProbeType::usdt && type != ProbeType::rawtracepoint)
957958
builtin.addError() << "The " << builtin.ident
958959
<< " builtin can only be used with "
959960
<< "'kprobes', 'uprobes' and 'usdt' probes";
961+
// argx in USDT probes doesn't need to check against arch::max_arg()
962+
if (type != ProbeType::usdt && arg_num > arch::max_arg())
963+
builtin.addError() << arch::name() << " doesn't support "
964+
<< builtin.ident;
960965
}
961-
int arg_num = atoi(builtin.ident.substr(3).c_str());
962-
if (arg_num > arch::max_arg())
963-
builtin.addError() << arch::name() << " doesn't support "
964-
<< builtin.ident;
965966
builtin.builtin_type = CreateUInt64();
966967
builtin.builtin_type.SetAS(addrspace);
967968
} else if (!builtin.ident.compare(0, 4, "sarg") &&

src/lexer.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ hspace [ \t]
4444
vspace [\n\r]
4545
space {hspace}|{vspace}
4646
path :(\\.|[_\-\./a-zA-Z0-9#$+\*])+
47-
builtin arg[0-9]|args|cgroup|comm|cpid|numaid|cpu|ncpus|ctx|curtask|elapsed|func|gid|pid|probe|rand|retval|sarg[0-9]|tid|uid|username|jiffies|nsecs|kstack|ustack
47+
builtin arg[0-9]+|args|cgroup|comm|cpid|numaid|cpu|ncpus|ctx|curtask|elapsed|func|gid|pid|probe|rand|retval|sarg[0-9]|tid|uid|username|jiffies|nsecs|kstack|ustack
4848

4949
int_type bool|(u)?int(8|16|32|64)
5050
builtin_type void|(u)?(min|max|sum|count|avg|stats)_t|probe_t|username|lhist_t|hist_t|usym_t|ksym_t|timestamp|macaddr_t|cgroup_path_t|strerror_t|kstack_t|ustack_t

tests/runtime/usdt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ EXPECT Attaching 3 probes...
132132

133133
NAME usdt probes - attach to probe on multiple files by wildcard
134134
PROG usdt:./testprogs/usdt*::* { printf("here\n" ); exit(); }
135-
EXPECT Attaching 48 probes...
135+
EXPECT Attaching 49 probes...
136136

137137
NAME usdt probes - attach to probe on multiple providers by wildcard and pid
138138
RUN {{BPFTRACE}} -e 'usdt:::*probe2 { printf("here\n" ); exit(); }' -p {{BEFORE_PID}}
@@ -287,3 +287,8 @@ RUN {{BPFTRACE}} runtime/scripts/usdt_multi_modules.bt
287287
EXPECT Attaching 2 probes...
288288
TIMEOUT 1
289289
REQUIRES ./testprogs/systemtap_sys_sdt_check
290+
291+
NAME usdt multi arguments
292+
RUN {{BPFTRACE}} -e 'usdt:./testprogs/usdt_multi_args:usdt_multi_args:probe1 { printf("%llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %lld %llx\n", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); exit(); }' -c ./testprogs/usdt_multi_args
293+
EXPECT deadbeef 1 ffffffffffffffff cafebabe 8badf00d feedface 123456789abcdef 0 7fffffffffffffff 5555555555555555 42 aaaaaaaaaaaaaaaa
294+
REQUIRES ./testprogs/systemtap_sys_sdt_check

tests/testprogs/usdt_multi_args.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifdef HAVE_SYSTEMTAP_SYS_SDT_H
2+
#include <sys/sdt.h>
3+
#else
4+
#define DTRACE_PROBE1(a, b, c) (void)0
5+
#endif
6+
#include <stdint.h>
7+
8+
int main()
9+
{
10+
uint32_t a = 0xdeadbeef;
11+
uint32_t b = 1;
12+
uint64_t c = UINT64_MAX;
13+
uint32_t d = 0xcafebabe;
14+
uint32_t e = 0x8badf00d;
15+
uint32_t f = 0xfeedface;
16+
uint64_t g = 0x0123456789abcdefULL;
17+
uint64_t h = 0x0ULL;
18+
uint64_t i = 0x7fffffffffffffffULL;
19+
uint64_t j = 0x5555555555555555ULL;
20+
uint32_t k = 42;
21+
uint64_t l = 0xaaaaaaaaaaaaaaaaULL;
22+
23+
while (1) {
24+
DTRACE_PROBE12(usdt_multi_args, probe1, a, b, c, d, e, f, g, h, i, j, k, l);
25+
}
26+
27+
return 0;
28+
}
29+

0 commit comments

Comments
 (0)