1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2016 Facebook
10 #include <linux/perf_event.h>
14 #include <sys/resource.h>
15 #include <bpf/libbpf.h>
17 #include "trace_helpers.h"
19 #define PRINT_RAW_ADDR 0
21 static void print_ksym(__u64 addr
)
27 sym
= ksym_search(addr
);
29 printf("ksym not found. Is kallsyms loaded?\n");
34 printf("%s/%llx;", sym
->name
, addr
);
36 printf("%s;", sym
->name
);
39 #define TASK_COMM_LEN 16
42 char waker
[TASK_COMM_LEN
];
43 char target
[TASK_COMM_LEN
];
48 static void print_stack(struct key_t
*key
, __u64 count
)
50 __u64 ip
[PERF_MAX_STACK_DEPTH
] = {};
54 printf("%s;", key
->target
);
55 if (bpf_map_lookup_elem(map_fd
[3], &key
->tret
, ip
) != 0) {
58 for (i
= PERF_MAX_STACK_DEPTH
- 1; i
>= 0; i
--)
62 if (bpf_map_lookup_elem(map_fd
[3], &key
->wret
, ip
) != 0) {
65 for (i
= 0; i
< PERF_MAX_STACK_DEPTH
; i
++)
68 printf(";%s %lld\n", key
->waker
, count
);
70 if ((key
->tret
== -EEXIST
|| key
->wret
== -EEXIST
) && !warned
) {
71 printf("stackmap collisions seen. Consider increasing size\n");
73 } else if (((int)(key
->tret
) < 0 || (int)(key
->wret
) < 0)) {
74 printf("err stackid %d %d\n", key
->tret
, key
->wret
);
78 static void print_stacks(int fd
)
80 struct key_t key
= {}, next_key
;
83 while (bpf_map_get_next_key(fd
, &key
, &next_key
) == 0) {
84 bpf_map_lookup_elem(fd
, &next_key
, &value
);
85 print_stack(&next_key
, value
);
90 static void int_exit(int sig
)
92 print_stacks(map_fd
[0]);
96 int main(int argc
, char **argv
)
98 struct rlimit r
= {RLIM_INFINITY
, RLIM_INFINITY
};
102 snprintf(filename
, sizeof(filename
), "%s_kern.o", argv
[0]);
103 setrlimit(RLIMIT_MEMLOCK
, &r
);
105 signal(SIGINT
, int_exit
);
106 signal(SIGTERM
, int_exit
);
108 if (load_kallsyms()) {
109 printf("failed to process /proc/kallsyms\n");
113 if (load_bpf_file(filename
)) {
114 printf("%s", bpf_log_buf
);
119 delay
= atoi(argv
[1]);
121 print_stacks(map_fd
[0]);