0001
0002
0003 #include "bpf_iter.h"
0004 #include <bpf/bpf_helpers.h>
0005
0006 char _license[] SEC("license") = "GPL";
0007
0008 #define MAX_STACK_TRACE_DEPTH 64
0009 unsigned long entries[MAX_STACK_TRACE_DEPTH] = {};
0010 #define SIZE_OF_ULONG (sizeof(unsigned long))
0011
0012 SEC("iter/task")
0013 int dump_task_stack(struct bpf_iter__task *ctx)
0014 {
0015 struct seq_file *seq = ctx->meta->seq;
0016 struct task_struct *task = ctx->task;
0017 long i, retlen;
0018
0019 if (task == (void *)0)
0020 return 0;
0021
0022 retlen = bpf_get_task_stack(task, entries,
0023 MAX_STACK_TRACE_DEPTH * SIZE_OF_ULONG, 0);
0024 if (retlen < 0)
0025 return 0;
0026
0027 BPF_SEQ_PRINTF(seq, "pid: %8u num_entries: %8u\n", task->pid,
0028 retlen / SIZE_OF_ULONG);
0029 for (i = 0; i < MAX_STACK_TRACE_DEPTH; i++) {
0030 if (retlen > i * SIZE_OF_ULONG)
0031 BPF_SEQ_PRINTF(seq, "[<0>] %pB\n", (void *)entries[i]);
0032 }
0033 BPF_SEQ_PRINTF(seq, "\n");
0034
0035 return 0;
0036 }
0037
0038 SEC("iter/task")
0039 int get_task_user_stacks(struct bpf_iter__task *ctx)
0040 {
0041 struct seq_file *seq = ctx->meta->seq;
0042 struct task_struct *task = ctx->task;
0043 uint64_t buf_sz = 0;
0044 int64_t res;
0045
0046 if (task == (void *)0)
0047 return 0;
0048
0049 res = bpf_get_task_stack(task, entries,
0050 MAX_STACK_TRACE_DEPTH * SIZE_OF_ULONG, BPF_F_USER_STACK);
0051 if (res <= 0)
0052 return 0;
0053
0054 buf_sz += res;
0055
0056
0057
0058
0059
0060
0061 bpf_seq_write(seq, &entries, buf_sz);
0062 return 0;
0063 }