1 /* Copyright (c) 2016 Facebook
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.
11 #include <linux/bpf.h>
13 #include <linux/perf_event.h>
17 #include <sys/resource.h>
21 #define PRINT_RAW_ADDR 0
23 static void print_ksym(__u64 addr
)
29 sym
= ksym_search(addr
);
31 printf("%s/%llx;", sym
->name
, addr
);
33 printf("%s;", sym
->name
);
36 #define TASK_COMM_LEN 16
39 char waker
[TASK_COMM_LEN
];
40 char target
[TASK_COMM_LEN
];
45 static void print_stack(struct key_t
*key
, __u64 count
)
47 __u64 ip
[PERF_MAX_STACK_DEPTH
] = {};
51 printf("%s;", key
->target
);
52 if (bpf_lookup_elem(map_fd
[3], &key
->tret
, ip
) != 0) {
55 for (i
= PERF_MAX_STACK_DEPTH
- 1; i
>= 0; i
--)
59 if (bpf_lookup_elem(map_fd
[3], &key
->wret
, ip
) != 0) {
62 for (i
= 0; i
< PERF_MAX_STACK_DEPTH
; i
++)
65 printf(";%s %lld\n", key
->waker
, count
);
67 if ((key
->tret
== -EEXIST
|| key
->wret
== -EEXIST
) && !warned
) {
68 printf("stackmap collisions seen. Consider increasing size\n");
70 } else if (((int)(key
->tret
) < 0 || (int)(key
->wret
) < 0)) {
71 printf("err stackid %d %d\n", key
->tret
, key
->wret
);
75 static void print_stacks(int fd
)
77 struct key_t key
= {}, next_key
;
80 while (bpf_get_next_key(fd
, &key
, &next_key
) == 0) {
81 bpf_lookup_elem(fd
, &next_key
, &value
);
82 print_stack(&next_key
, value
);
87 static void int_exit(int sig
)
89 print_stacks(map_fd
[0]);
93 int main(int argc
, char **argv
)
95 struct rlimit r
= {RLIM_INFINITY
, RLIM_INFINITY
};
99 snprintf(filename
, sizeof(filename
), "%s_kern.o", argv
[0]);
100 setrlimit(RLIMIT_MEMLOCK
, &r
);
102 signal(SIGINT
, int_exit
);
104 if (load_kallsyms()) {
105 printf("failed to process /proc/kallsyms\n");
109 if (load_bpf_file(filename
)) {
110 printf("%s", bpf_log_buf
);
115 delay
= atoi(argv
[1]);
117 print_stacks(map_fd
[0]);