.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* Copyright (c) 2016 Facebook |
---|
2 | | - * |
---|
3 | | - * This program is free software; you can redistribute it and/or |
---|
4 | | - * modify it under the terms of version 2 of the GNU General Public |
---|
5 | | - * License as published by the Free Software Foundation. |
---|
6 | 3 | */ |
---|
7 | 4 | #include <stdio.h> |
---|
8 | 5 | #include <unistd.h> |
---|
9 | 6 | #include <stdlib.h> |
---|
10 | 7 | #include <signal.h> |
---|
11 | | -#include <linux/bpf.h> |
---|
12 | | -#include <string.h> |
---|
13 | 8 | #include <linux/perf_event.h> |
---|
14 | 9 | #include <errno.h> |
---|
15 | | -#include <assert.h> |
---|
16 | 10 | #include <stdbool.h> |
---|
17 | 11 | #include <sys/resource.h> |
---|
18 | | -#include "libbpf.h" |
---|
19 | | -#include "bpf_load.h" |
---|
| 12 | +#include <bpf/libbpf.h> |
---|
| 13 | +#include <bpf/bpf.h> |
---|
20 | 14 | #include "trace_helpers.h" |
---|
21 | 15 | |
---|
22 | 16 | #define PRINT_RAW_ADDR 0 |
---|
| 17 | + |
---|
| 18 | +/* counts, stackmap */ |
---|
| 19 | +static int map_fd[2]; |
---|
23 | 20 | |
---|
24 | 21 | static void print_ksym(__u64 addr) |
---|
25 | 22 | { |
---|
.. | .. |
---|
28 | 25 | if (!addr) |
---|
29 | 26 | return; |
---|
30 | 27 | sym = ksym_search(addr); |
---|
| 28 | + if (!sym) { |
---|
| 29 | + printf("ksym not found. Is kallsyms loaded?\n"); |
---|
| 30 | + return; |
---|
| 31 | + } |
---|
| 32 | + |
---|
31 | 33 | if (PRINT_RAW_ADDR) |
---|
32 | 34 | printf("%s/%llx;", sym->name, addr); |
---|
33 | 35 | else |
---|
.. | .. |
---|
50 | 52 | int i; |
---|
51 | 53 | |
---|
52 | 54 | printf("%s;", key->target); |
---|
53 | | - if (bpf_map_lookup_elem(map_fd[3], &key->tret, ip) != 0) { |
---|
| 55 | + if (bpf_map_lookup_elem(map_fd[1], &key->tret, ip) != 0) { |
---|
54 | 56 | printf("---;"); |
---|
55 | 57 | } else { |
---|
56 | 58 | for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--) |
---|
57 | 59 | print_ksym(ip[i]); |
---|
58 | 60 | } |
---|
59 | 61 | printf("-;"); |
---|
60 | | - if (bpf_map_lookup_elem(map_fd[3], &key->wret, ip) != 0) { |
---|
| 62 | + if (bpf_map_lookup_elem(map_fd[1], &key->wret, ip) != 0) { |
---|
61 | 63 | printf("---;"); |
---|
62 | 64 | } else { |
---|
63 | 65 | for (i = 0; i < PERF_MAX_STACK_DEPTH; i++) |
---|
.. | .. |
---|
94 | 96 | int main(int argc, char **argv) |
---|
95 | 97 | { |
---|
96 | 98 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; |
---|
| 99 | + struct bpf_object *obj = NULL; |
---|
| 100 | + struct bpf_link *links[2]; |
---|
| 101 | + struct bpf_program *prog; |
---|
| 102 | + int delay = 1, i = 0; |
---|
97 | 103 | char filename[256]; |
---|
98 | | - int delay = 1; |
---|
99 | 104 | |
---|
100 | | - snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
---|
101 | | - setrlimit(RLIMIT_MEMLOCK, &r); |
---|
102 | | - |
---|
103 | | - signal(SIGINT, int_exit); |
---|
104 | | - signal(SIGTERM, int_exit); |
---|
| 105 | + if (setrlimit(RLIMIT_MEMLOCK, &r)) { |
---|
| 106 | + perror("setrlimit(RLIMIT_MEMLOCK)"); |
---|
| 107 | + return 1; |
---|
| 108 | + } |
---|
105 | 109 | |
---|
106 | 110 | if (load_kallsyms()) { |
---|
107 | 111 | printf("failed to process /proc/kallsyms\n"); |
---|
108 | 112 | return 2; |
---|
109 | 113 | } |
---|
110 | 114 | |
---|
111 | | - if (load_bpf_file(filename)) { |
---|
112 | | - printf("%s", bpf_log_buf); |
---|
113 | | - return 1; |
---|
| 115 | + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
---|
| 116 | + obj = bpf_object__open_file(filename, NULL); |
---|
| 117 | + if (libbpf_get_error(obj)) { |
---|
| 118 | + fprintf(stderr, "ERROR: opening BPF object file failed\n"); |
---|
| 119 | + obj = NULL; |
---|
| 120 | + goto cleanup; |
---|
| 121 | + } |
---|
| 122 | + |
---|
| 123 | + /* load BPF program */ |
---|
| 124 | + if (bpf_object__load(obj)) { |
---|
| 125 | + fprintf(stderr, "ERROR: loading BPF object file failed\n"); |
---|
| 126 | + goto cleanup; |
---|
| 127 | + } |
---|
| 128 | + |
---|
| 129 | + map_fd[0] = bpf_object__find_map_fd_by_name(obj, "counts"); |
---|
| 130 | + map_fd[1] = bpf_object__find_map_fd_by_name(obj, "stackmap"); |
---|
| 131 | + if (map_fd[0] < 0 || map_fd[1] < 0) { |
---|
| 132 | + fprintf(stderr, "ERROR: finding a map in obj file failed\n"); |
---|
| 133 | + goto cleanup; |
---|
| 134 | + } |
---|
| 135 | + |
---|
| 136 | + signal(SIGINT, int_exit); |
---|
| 137 | + signal(SIGTERM, int_exit); |
---|
| 138 | + |
---|
| 139 | + bpf_object__for_each_program(prog, obj) { |
---|
| 140 | + links[i] = bpf_program__attach(prog); |
---|
| 141 | + if (libbpf_get_error(links[i])) { |
---|
| 142 | + fprintf(stderr, "ERROR: bpf_program__attach failed\n"); |
---|
| 143 | + links[i] = NULL; |
---|
| 144 | + goto cleanup; |
---|
| 145 | + } |
---|
| 146 | + i++; |
---|
114 | 147 | } |
---|
115 | 148 | |
---|
116 | 149 | if (argc > 1) |
---|
.. | .. |
---|
118 | 151 | sleep(delay); |
---|
119 | 152 | print_stacks(map_fd[0]); |
---|
120 | 153 | |
---|
| 154 | +cleanup: |
---|
| 155 | + for (i--; i >= 0; i--) |
---|
| 156 | + bpf_link__destroy(links[i]); |
---|
| 157 | + |
---|
| 158 | + bpf_object__close(obj); |
---|
121 | 159 | return 0; |
---|
122 | 160 | } |
---|