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("ksym not found. Is kallsyms loaded?\n");
37 printf("%s/%llx;", sym
->name
, addr
);
39 printf("%s;", sym
->name
);
42 #define TASK_COMM_LEN 16
45 char waker
[TASK_COMM_LEN
];
46 char target
[TASK_COMM_LEN
];
51 static void print_stack(struct key_t
*key
, __u64 count
)
53 __u64 ip
[PERF_MAX_STACK_DEPTH
] = {};
57 printf("%s;", key
->target
);
58 if (bpf_map_lookup_elem(map_fd
[3], &key
->tret
, ip
) != 0) {
61 for (i
= PERF_MAX_STACK_DEPTH
- 1; i
>= 0; i
--)
65 if (bpf_map_lookup_elem(map_fd
[3], &key
->wret
, ip
) != 0) {
68 for (i
= 0; i
< PERF_MAX_STACK_DEPTH
; i
++)
71 printf(";%s %lld\n", key
->waker
, count
);
73 if ((key
->tret
== -EEXIST
|| key
->wret
== -EEXIST
) && !warned
) {
74 printf("stackmap collisions seen. Consider increasing size\n");
76 } else if (((int)(key
->tret
) < 0 || (int)(key
->wret
) < 0)) {
77 printf("err stackid %d %d\n", key
->tret
, key
->wret
);
81 static void print_stacks(int fd
)
83 struct key_t key
= {}, next_key
;
86 while (bpf_map_get_next_key(fd
, &key
, &next_key
) == 0) {
87 bpf_map_lookup_elem(fd
, &next_key
, &value
);
88 print_stack(&next_key
, value
);
93 static void int_exit(int sig
)
95 print_stacks(map_fd
[0]);
99 int main(int argc
, char **argv
)
101 struct rlimit r
= {RLIM_INFINITY
, RLIM_INFINITY
};
105 snprintf(filename
, sizeof(filename
), "%s_kern.o", argv
[0]);
106 setrlimit(RLIMIT_MEMLOCK
, &r
);
108 signal(SIGINT
, int_exit
);
109 signal(SIGTERM
, int_exit
);
111 if (load_kallsyms()) {
112 printf("failed to process /proc/kallsyms\n");
116 if (load_bpf_file(filename
)) {
117 printf("%s", bpf_log_buf
);
122 delay
= atoi(argv
[1]);
124 print_stacks(map_fd
[0]);