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>
20 #include "trace_helpers.h"
22 #define PRINT_RAW_ADDR 0
24 static void print_ksym(__u64 addr
)
30 sym
= ksym_search(addr
);
32 printf("%s/%llx;", sym
->name
, addr
);
34 printf("%s;", sym
->name
);
37 #define TASK_COMM_LEN 16
40 char waker
[TASK_COMM_LEN
];
41 char target
[TASK_COMM_LEN
];
46 static void print_stack(struct key_t
*key
, __u64 count
)
48 __u64 ip
[PERF_MAX_STACK_DEPTH
] = {};
52 printf("%s;", key
->target
);
53 if (bpf_map_lookup_elem(map_fd
[3], &key
->tret
, ip
) != 0) {
56 for (i
= PERF_MAX_STACK_DEPTH
- 1; i
>= 0; i
--)
60 if (bpf_map_lookup_elem(map_fd
[3], &key
->wret
, ip
) != 0) {
63 for (i
= 0; i
< PERF_MAX_STACK_DEPTH
; i
++)
66 printf(";%s %lld\n", key
->waker
, count
);
68 if ((key
->tret
== -EEXIST
|| key
->wret
== -EEXIST
) && !warned
) {
69 printf("stackmap collisions seen. Consider increasing size\n");
71 } else if (((int)(key
->tret
) < 0 || (int)(key
->wret
) < 0)) {
72 printf("err stackid %d %d\n", key
->tret
, key
->wret
);
76 static void print_stacks(int fd
)
78 struct key_t key
= {}, next_key
;
81 while (bpf_map_get_next_key(fd
, &key
, &next_key
) == 0) {
82 bpf_map_lookup_elem(fd
, &next_key
, &value
);
83 print_stack(&next_key
, value
);
88 static void int_exit(int sig
)
90 print_stacks(map_fd
[0]);
94 int main(int argc
, char **argv
)
96 struct rlimit r
= {RLIM_INFINITY
, RLIM_INFINITY
};
100 snprintf(filename
, sizeof(filename
), "%s_kern.o", argv
[0]);
101 setrlimit(RLIMIT_MEMLOCK
, &r
);
103 signal(SIGINT
, int_exit
);
104 signal(SIGTERM
, int_exit
);
106 if (load_kallsyms()) {
107 printf("failed to process /proc/kallsyms\n");
111 if (load_bpf_file(filename
)) {
112 printf("%s", bpf_log_buf
);
117 delay
= atoi(argv
[1]);
119 print_stacks(map_fd
[0]);