staticconstchar *get_task_state(__u32 state) { /* Taken from: * https://elixir.bootlin.com/linux/latest/source/include/linux/sched.h#L85 * There are a lot more states not covered here but these are common ones. */ switch (state) { case0x0000: return"RUNNING"; case0x0001: return"INTERRUPTIBLE"; case0x0002: return"UNINTERRUPTIBLE"; case0x0200: return"WAKING"; case0x0400: return"NOLOAD"; case0x0402: return"IDLE"; case0x0800: return"NEW"; default: return"<unknown>"; } }
open_and_load
1 2 3 4 5 6
/* Open, load, and verify BPF application */ skel = task_iter_bpf__open_and_load(); if (!skel) { fprintf(stderr, "Failed to open and load BPF skeleton\n"); goto cleanup; }
/* Attach BPF iterator program */ memset(&linfo, 0, sizeof(linfo)); linfo.task.pid = pid_filter; /* If the pid is set to zero, no filtering logic is applied */ opts.link_info = &linfo; opts.link_info_len = sizeof(linfo);
bpf_program__attach_iter
1 2 3 4 5 6 7 8 9 10 11 12 13 14
skel->links.get_tasks = bpf_program__attach_iter(skel->progs.get_tasks, &opts); if (!skel->links.get_tasks) { err = -errno; fprintf(stderr, "Failed to attach BPF skeleton\n"); goto cleanup; } /* Alternatively, if the user doesn't want to provide any option, the following simplified * version can be used: * err = task_iter_bpf__attach(skel); * if (err) { * fprintf(stderr, "Failed to attach BPF skeleton\n"); * goto cleanup; * } */
bpf_iter_create
1 2 3 4 5 6
iter_fd = bpf_iter_create(bpf_link__fd(skel->links.get_tasks)); if (iter_fd < 0) { err = -1; fprintf(stderr, "Failed to create iter\n"); goto cleanup; }
while
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
while (true) { ret = read(iter_fd, &buf, sizeof(struct task_info)); if (ret < 0) { if (errno == EAGAIN) continue; err = -errno; break; } if (ret == 0) break; if (buf.kstack_len <= 0) { printf("Error getting kernel stack for task. Task Info. Pid: %d. Process Name: %s. Kernel Stack Error: %d. State: %s\n", buf.pid, buf.comm, buf.kstack_len, get_task_state(buf.state)); } else { printf("Task Info. Pid: %d. Process Name: %s. Kernel Stack Len: %d. State: %s\n", buf.pid, buf.comm, buf.kstack_len, get_task_state(buf.state)); } }
cleanup
1 2 3 4
cleanup: /* Clean up */ close(iter_fd); task_iter_bpf__destroy(skel);