1*387f9dfdSAndroid Build Coastguard Worker /*
2*387f9dfdSAndroid Build Coastguard Worker * Copyright (c) Facebook, Inc.
3*387f9dfdSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License")
4*387f9dfdSAndroid Build Coastguard Worker *
5*387f9dfdSAndroid Build Coastguard Worker * Usage:
6*387f9dfdSAndroid Build Coastguard Worker * ./TaskIterator
7*387f9dfdSAndroid Build Coastguard Worker *
8*387f9dfdSAndroid Build Coastguard Worker * BPF task iterator is available since linux 5.8.
9*387f9dfdSAndroid Build Coastguard Worker * This example shows how to dump all threads in the system with
10*387f9dfdSAndroid Build Coastguard Worker * bpf iterator. An example output likes below:
11*387f9dfdSAndroid Build Coastguard Worker * tid comm
12*387f9dfdSAndroid Build Coastguard Worker * 1 systemd
13*387f9dfdSAndroid Build Coastguard Worker * 2 kthreadd
14*387f9dfdSAndroid Build Coastguard Worker * 3 rcu_gp
15*387f9dfdSAndroid Build Coastguard Worker * 4 rcu_par_gp
16*387f9dfdSAndroid Build Coastguard Worker * 6 kworker/0:0H
17*387f9dfdSAndroid Build Coastguard Worker * ...
18*387f9dfdSAndroid Build Coastguard Worker * 2613386 sleep
19*387f9dfdSAndroid Build Coastguard Worker * 2613474 GetCountersCPU6
20*387f9dfdSAndroid Build Coastguard Worker * 2613587 GetCountersCPU7
21*387f9dfdSAndroid Build Coastguard Worker * 2613621 CPUThreadPool69
22*387f9dfdSAndroid Build Coastguard Worker * 2613906 GetCountersCPU5
23*387f9dfdSAndroid Build Coastguard Worker * 2614140 GetCountersCPU2
24*387f9dfdSAndroid Build Coastguard Worker * 2614193 CfgrExtension56
25*387f9dfdSAndroid Build Coastguard Worker * 2614449 ruby-timer-thr
26*387f9dfdSAndroid Build Coastguard Worker * 2614529 chef-client
27*387f9dfdSAndroid Build Coastguard Worker * 2615122 systemd-hostnam
28*387f9dfdSAndroid Build Coastguard Worker * ...
29*387f9dfdSAndroid Build Coastguard Worker * 2608477 sudo
30*387f9dfdSAndroid Build Coastguard Worker * 2608478 TaskIterator
31*387f9dfdSAndroid Build Coastguard Worker */
32*387f9dfdSAndroid Build Coastguard Worker
33*387f9dfdSAndroid Build Coastguard Worker #include <unistd.h>
34*387f9dfdSAndroid Build Coastguard Worker #include <fstream>
35*387f9dfdSAndroid Build Coastguard Worker #include <iostream>
36*387f9dfdSAndroid Build Coastguard Worker #include <string>
37*387f9dfdSAndroid Build Coastguard Worker
38*387f9dfdSAndroid Build Coastguard Worker #include "bcc_version.h"
39*387f9dfdSAndroid Build Coastguard Worker #include "BPF.h"
40*387f9dfdSAndroid Build Coastguard Worker
41*387f9dfdSAndroid Build Coastguard Worker const std::string BPF_PROGRAM = R"(
42*387f9dfdSAndroid Build Coastguard Worker #include <linux/bpf.h>
43*387f9dfdSAndroid Build Coastguard Worker #include <linux/seq_file.h>
44*387f9dfdSAndroid Build Coastguard Worker #include <linux/sched.h>
45*387f9dfdSAndroid Build Coastguard Worker
46*387f9dfdSAndroid Build Coastguard Worker /* the structure is defined in .c file, so explicitly define
47*387f9dfdSAndroid Build Coastguard Worker * the structure here.
48*387f9dfdSAndroid Build Coastguard Worker */
49*387f9dfdSAndroid Build Coastguard Worker struct bpf_iter__task {
50*387f9dfdSAndroid Build Coastguard Worker union {
51*387f9dfdSAndroid Build Coastguard Worker struct bpf_iter_meta *meta;
52*387f9dfdSAndroid Build Coastguard Worker };
53*387f9dfdSAndroid Build Coastguard Worker union {
54*387f9dfdSAndroid Build Coastguard Worker struct task_struct *task;
55*387f9dfdSAndroid Build Coastguard Worker };
56*387f9dfdSAndroid Build Coastguard Worker };
57*387f9dfdSAndroid Build Coastguard Worker
58*387f9dfdSAndroid Build Coastguard Worker struct info_t {
59*387f9dfdSAndroid Build Coastguard Worker int tid;
60*387f9dfdSAndroid Build Coastguard Worker char comm[TASK_COMM_LEN];
61*387f9dfdSAndroid Build Coastguard Worker };
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker BPF_ITER(task) {
64*387f9dfdSAndroid Build Coastguard Worker struct seq_file *seq = ctx->meta->seq;
65*387f9dfdSAndroid Build Coastguard Worker struct task_struct *task = ctx->task;
66*387f9dfdSAndroid Build Coastguard Worker struct info_t info = {};
67*387f9dfdSAndroid Build Coastguard Worker
68*387f9dfdSAndroid Build Coastguard Worker if (task == (void *)0)
69*387f9dfdSAndroid Build Coastguard Worker return 0;
70*387f9dfdSAndroid Build Coastguard Worker
71*387f9dfdSAndroid Build Coastguard Worker info.tid = task->pid;
72*387f9dfdSAndroid Build Coastguard Worker __builtin_memcpy(&info.comm, task->comm, sizeof(info.comm));
73*387f9dfdSAndroid Build Coastguard Worker bpf_seq_write(seq, &info, sizeof(info));
74*387f9dfdSAndroid Build Coastguard Worker
75*387f9dfdSAndroid Build Coastguard Worker return 0;
76*387f9dfdSAndroid Build Coastguard Worker }
77*387f9dfdSAndroid Build Coastguard Worker )";
78*387f9dfdSAndroid Build Coastguard Worker
79*387f9dfdSAndroid Build Coastguard Worker // linux/sched.h
80*387f9dfdSAndroid Build Coastguard Worker #define TASK_COMM_LEN 16
81*387f9dfdSAndroid Build Coastguard Worker
82*387f9dfdSAndroid Build Coastguard Worker struct info_t {
83*387f9dfdSAndroid Build Coastguard Worker int tid;
84*387f9dfdSAndroid Build Coastguard Worker char comm[TASK_COMM_LEN];
85*387f9dfdSAndroid Build Coastguard Worker };
86*387f9dfdSAndroid Build Coastguard Worker
main()87*387f9dfdSAndroid Build Coastguard Worker int main() {
88*387f9dfdSAndroid Build Coastguard Worker ebpf::BPF bpf;
89*387f9dfdSAndroid Build Coastguard Worker auto res = bpf.init(BPF_PROGRAM);
90*387f9dfdSAndroid Build Coastguard Worker if (!res.ok()) {
91*387f9dfdSAndroid Build Coastguard Worker std::cerr << res.msg() << std::endl;
92*387f9dfdSAndroid Build Coastguard Worker return 1;
93*387f9dfdSAndroid Build Coastguard Worker }
94*387f9dfdSAndroid Build Coastguard Worker
95*387f9dfdSAndroid Build Coastguard Worker int prog_fd;
96*387f9dfdSAndroid Build Coastguard Worker res = bpf.load_func("bpf_iter__task", BPF_PROG_TYPE_TRACING, prog_fd);
97*387f9dfdSAndroid Build Coastguard Worker if (!res.ok()) {
98*387f9dfdSAndroid Build Coastguard Worker std::cerr << res.msg() << std::endl;
99*387f9dfdSAndroid Build Coastguard Worker return 1;
100*387f9dfdSAndroid Build Coastguard Worker }
101*387f9dfdSAndroid Build Coastguard Worker
102*387f9dfdSAndroid Build Coastguard Worker int link_fd = bcc_iter_attach(prog_fd, NULL, 0);
103*387f9dfdSAndroid Build Coastguard Worker if (link_fd < 0) {
104*387f9dfdSAndroid Build Coastguard Worker std::cerr << "bcc_iter_attach failed: " << link_fd << std::endl;
105*387f9dfdSAndroid Build Coastguard Worker return 1;
106*387f9dfdSAndroid Build Coastguard Worker }
107*387f9dfdSAndroid Build Coastguard Worker
108*387f9dfdSAndroid Build Coastguard Worker int iter_fd = bcc_iter_create(link_fd);
109*387f9dfdSAndroid Build Coastguard Worker if (iter_fd < 0) {
110*387f9dfdSAndroid Build Coastguard Worker std::cerr << "bcc_iter_create failed: " << iter_fd << std::endl;
111*387f9dfdSAndroid Build Coastguard Worker close(link_fd);
112*387f9dfdSAndroid Build Coastguard Worker return 1;
113*387f9dfdSAndroid Build Coastguard Worker }
114*387f9dfdSAndroid Build Coastguard Worker
115*387f9dfdSAndroid Build Coastguard Worker // Header.
116*387f9dfdSAndroid Build Coastguard Worker printf("tid\tcomm\n");
117*387f9dfdSAndroid Build Coastguard Worker
118*387f9dfdSAndroid Build Coastguard Worker struct info_t info[20];
119*387f9dfdSAndroid Build Coastguard Worker int len, leftover = 0, info_size = 20 * sizeof(struct info_t);
120*387f9dfdSAndroid Build Coastguard Worker while ((len = read(iter_fd, (char *)info + leftover, info_size - leftover))) {
121*387f9dfdSAndroid Build Coastguard Worker if (len < 0) {
122*387f9dfdSAndroid Build Coastguard Worker if (len == -EAGAIN)
123*387f9dfdSAndroid Build Coastguard Worker continue;
124*387f9dfdSAndroid Build Coastguard Worker std::cerr << "read failed: " << len << std::endl;
125*387f9dfdSAndroid Build Coastguard Worker break;
126*387f9dfdSAndroid Build Coastguard Worker }
127*387f9dfdSAndroid Build Coastguard Worker
128*387f9dfdSAndroid Build Coastguard Worker int num_info = len / sizeof(struct info_t);
129*387f9dfdSAndroid Build Coastguard Worker for (int i = 0; i < num_info; i++) {
130*387f9dfdSAndroid Build Coastguard Worker printf("%d\t%s\n", info[i].tid, info[i].comm);
131*387f9dfdSAndroid Build Coastguard Worker }
132*387f9dfdSAndroid Build Coastguard Worker
133*387f9dfdSAndroid Build Coastguard Worker leftover = len % sizeof(struct info_t);
134*387f9dfdSAndroid Build Coastguard Worker if (num_info > 0)
135*387f9dfdSAndroid Build Coastguard Worker memcpy(info, (void *)&info[num_info], leftover);
136*387f9dfdSAndroid Build Coastguard Worker }
137*387f9dfdSAndroid Build Coastguard Worker
138*387f9dfdSAndroid Build Coastguard Worker close(iter_fd);
139*387f9dfdSAndroid Build Coastguard Worker close(link_fd);
140*387f9dfdSAndroid Build Coastguard Worker return 0;
141*387f9dfdSAndroid Build Coastguard Worker }
142