Skip to content

Commit 2e14aa1

Browse files
committed
selftests/bpf: add BPF program dump in veristat
This patch adds support for dumping BPF program instructions directly from veristat. While it is already possible to inspect BPF program dump using bpftool, it requires multiple commands. During active development, it's common for developers to use veristat for testing verification. Integrating instruction dumping into veristat reduces the need to switch tools and simplifies the workflow. By making this information more readily accessible, this change aims to streamline the BPF development cycle and improve usability for developers. Signed-off-by: Mykyta Yatsenko <[email protected]>
1 parent fa47913 commit 2e14aa1

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

tools/testing/selftests/bpf/veristat.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ struct var_preset {
181181
bool applied;
182182
};
183183

184+
enum dump_mode {
185+
NO_DUMP = 0,
186+
XLATED,
187+
JITED,
188+
};
189+
184190
static struct env {
185191
char **filenames;
186192
int filename_cnt;
@@ -227,6 +233,7 @@ static struct env {
227233
char orig_cgroup[PATH_MAX];
228234
char stat_cgroup[PATH_MAX];
229235
int memory_peak_fd;
236+
enum dump_mode dump_mode;
230237
} env;
231238

232239
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
@@ -295,6 +302,7 @@ static const struct argp_option opts[] = {
295302
"Force BPF verifier failure on register invariant violation (BPF_F_TEST_REG_INVARIANTS program flag)" },
296303
{ "top-src-lines", 'S', "N", 0, "Emit N most frequent source code lines" },
297304
{ "set-global-vars", 'G', "GLOBAL", 0, "Set global variables provided in the expression, for example \"var1 = 1\"" },
305+
{ "dump", 'p', "DUMP", 0, "Print BPF program dump" },
298306
{},
299307
};
300308

@@ -427,6 +435,16 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
427435
return err;
428436
}
429437
break;
438+
case 'p':
439+
if (strcmp(arg, "jited") == 0) {
440+
env.dump_mode = JITED;
441+
} else if (strcmp(arg, "xlated") == 0) {
442+
env.dump_mode = XLATED;
443+
} else {
444+
fprintf(stderr, "Unrecognized dump mode '%s'\n", arg);
445+
return -EINVAL;
446+
}
447+
break;
430448
default:
431449
return ARGP_ERR_UNKNOWN;
432450
}
@@ -1554,6 +1572,27 @@ static int parse_rvalue(const char *val, struct rvalue *rvalue)
15541572
return 0;
15551573
}
15561574

1575+
static void dump(int prog_fd)
1576+
{
1577+
char command[512];
1578+
char buf[1024];
1579+
FILE *fp;
1580+
1581+
snprintf(command, sizeof(command), "bpftool prog dump %s id %d",
1582+
env.dump_mode == JITED ? "jited" : "xlated", prog_fd);
1583+
fp = popen(command, "r");
1584+
if (!fp) {
1585+
fprintf(stderr, "Can't run bpftool\n");
1586+
return;
1587+
}
1588+
1589+
while (fgets(buf, sizeof(buf), fp)) {
1590+
printf("%s", buf);
1591+
}
1592+
1593+
pclose(fp);
1594+
}
1595+
15571596
static int process_prog(const char *filename, struct bpf_object *obj, struct bpf_program *prog)
15581597
{
15591598
const char *base_filename = basename(strdupa(filename));
@@ -1630,8 +1669,11 @@ static int process_prog(const char *filename, struct bpf_object *obj, struct bpf
16301669

16311670
memset(&info, 0, info_len);
16321671
fd = bpf_program__fd(prog);
1633-
if (fd > 0 && bpf_prog_get_info_by_fd(fd, &info, &info_len) == 0)
1672+
if (fd > 0 && bpf_prog_get_info_by_fd(fd, &info, &info_len) == 0) {
16341673
stats->stats[JITED_SIZE] = info.jited_prog_len;
1674+
if (env.dump_mode != NO_DUMP)
1675+
dump(info.id);
1676+
}
16351677

16361678
parse_verif_log(buf, buf_sz, stats);
16371679

0 commit comments

Comments
 (0)