0001
0002
0003 #include <linux/bpf.h>
0004 #include <bpf/bpf_helpers.h>
0005
0006
0007 #define MAX_STACK_RAWTP 100
0008 struct stack_trace_t {
0009 int pid;
0010 int kern_stack_size;
0011 int user_stack_size;
0012 int user_stack_buildid_size;
0013 __u64 kern_stack[MAX_STACK_RAWTP];
0014 __u64 user_stack[MAX_STACK_RAWTP];
0015 struct bpf_stack_build_id user_stack_buildid[MAX_STACK_RAWTP];
0016 };
0017
0018 struct {
0019 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
0020 __uint(max_entries, 2);
0021 __uint(key_size, sizeof(int));
0022 __uint(value_size, sizeof(__u32));
0023 } perfmap SEC(".maps");
0024
0025 struct {
0026 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
0027 __uint(max_entries, 1);
0028 __type(key, __u32);
0029 __type(value, struct stack_trace_t);
0030 } stackdata_map SEC(".maps");
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 struct {
0051 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
0052 __uint(max_entries, 1);
0053 __type(key, __u32);
0054 __type(value, __u64[2 * MAX_STACK_RAWTP]);
0055 } rawdata_map SEC(".maps");
0056
0057 SEC("raw_tracepoint/sys_enter")
0058 int bpf_prog1(void *ctx)
0059 {
0060 int max_len, max_buildid_len, total_size;
0061 struct stack_trace_t *data;
0062 long usize, ksize;
0063 void *raw_data;
0064 __u32 key = 0;
0065
0066 data = bpf_map_lookup_elem(&stackdata_map, &key);
0067 if (!data)
0068 return 0;
0069
0070 max_len = MAX_STACK_RAWTP * sizeof(__u64);
0071 max_buildid_len = MAX_STACK_RAWTP * sizeof(struct bpf_stack_build_id);
0072 data->pid = bpf_get_current_pid_tgid();
0073 data->kern_stack_size = bpf_get_stack(ctx, data->kern_stack,
0074 max_len, 0);
0075 data->user_stack_size = bpf_get_stack(ctx, data->user_stack, max_len,
0076 BPF_F_USER_STACK);
0077 data->user_stack_buildid_size = bpf_get_stack(
0078 ctx, data->user_stack_buildid, max_buildid_len,
0079 BPF_F_USER_STACK | BPF_F_USER_BUILD_ID);
0080 bpf_perf_event_output(ctx, &perfmap, 0, data, sizeof(*data));
0081
0082
0083 raw_data = bpf_map_lookup_elem(&rawdata_map, &key);
0084 if (!raw_data)
0085 return 0;
0086
0087 usize = bpf_get_stack(ctx, raw_data, max_len, BPF_F_USER_STACK);
0088 if (usize < 0)
0089 return 0;
0090
0091 ksize = bpf_get_stack(ctx, raw_data + usize, max_len - usize, 0);
0092 if (ksize < 0)
0093 return 0;
0094
0095 total_size = usize + ksize;
0096 if (total_size > 0 && total_size <= max_len)
0097 bpf_perf_event_output(ctx, &perfmap, 0, raw_data, total_size);
0098
0099 return 0;
0100 }
0101
0102 char _license[] SEC("license") = "GPL";