xref: /linux/Documentation/bpf/drgn.rst (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
1*8c061865SAndrey Ignatov.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2*8c061865SAndrey Ignatov
3*8c061865SAndrey Ignatov==============
4*8c061865SAndrey IgnatovBPF drgn tools
5*8c061865SAndrey Ignatov==============
6*8c061865SAndrey Ignatov
7*8c061865SAndrey Ignatovdrgn scripts is a convenient and easy to use mechanism to retrieve arbitrary
8*8c061865SAndrey Ignatovkernel data structures. drgn is not relying on kernel UAPI to read the data.
9*8c061865SAndrey IgnatovInstead it's reading directly from ``/proc/kcore`` or vmcore and pretty prints
10*8c061865SAndrey Ignatovthe data based on DWARF debug information from vmlinux.
11*8c061865SAndrey Ignatov
12*8c061865SAndrey IgnatovThis document describes BPF related drgn tools.
13*8c061865SAndrey Ignatov
14*8c061865SAndrey IgnatovSee `drgn/tools`_ for all tools available at the moment and `drgn/doc`_ for
15*8c061865SAndrey Ignatovmore details on drgn itself.
16*8c061865SAndrey Ignatov
17*8c061865SAndrey Ignatovbpf_inspect.py
18*8c061865SAndrey Ignatov--------------
19*8c061865SAndrey Ignatov
20*8c061865SAndrey IgnatovDescription
21*8c061865SAndrey Ignatov===========
22*8c061865SAndrey Ignatov
23*8c061865SAndrey Ignatov`bpf_inspect.py`_ is a tool intended to inspect BPF programs and maps. It can
24*8c061865SAndrey Ignatoviterate over all programs and maps in the system and print basic information
25*8c061865SAndrey Ignatovabout these objects, including id, type and name.
26*8c061865SAndrey Ignatov
27*8c061865SAndrey IgnatovThe main use-case `bpf_inspect.py`_ covers is to show BPF programs of types
28*8c061865SAndrey Ignatov``BPF_PROG_TYPE_EXT`` and ``BPF_PROG_TYPE_TRACING`` attached to other BPF
29*8c061865SAndrey Ignatovprograms via ``freplace``/``fentry``/``fexit`` mechanisms, since there is no
30*8c061865SAndrey Ignatovuser-space API to get this information.
31*8c061865SAndrey Ignatov
32*8c061865SAndrey IgnatovGetting started
33*8c061865SAndrey Ignatov===============
34*8c061865SAndrey Ignatov
35*8c061865SAndrey IgnatovList BPF programs (full names are obtained from BTF)::
36*8c061865SAndrey Ignatov
37*8c061865SAndrey Ignatov    % sudo bpf_inspect.py prog
38*8c061865SAndrey Ignatov        27: BPF_PROG_TYPE_TRACEPOINT         tracepoint__tcp__tcp_send_reset
39*8c061865SAndrey Ignatov      4632: BPF_PROG_TYPE_CGROUP_SOCK_ADDR   tw_ipt_bind
40*8c061865SAndrey Ignatov     49464: BPF_PROG_TYPE_RAW_TRACEPOINT     raw_tracepoint__sched_process_exit
41*8c061865SAndrey Ignatov
42*8c061865SAndrey IgnatovList BPF maps::
43*8c061865SAndrey Ignatov
44*8c061865SAndrey Ignatov      % sudo bpf_inspect.py map
45*8c061865SAndrey Ignatov        2577: BPF_MAP_TYPE_HASH                tw_ipt_vips
46*8c061865SAndrey Ignatov        4050: BPF_MAP_TYPE_STACK_TRACE         stack_traces
47*8c061865SAndrey Ignatov        4069: BPF_MAP_TYPE_PERCPU_ARRAY        ned_dctcp_cntr
48*8c061865SAndrey Ignatov
49*8c061865SAndrey IgnatovFind BPF programs attached to BPF program ``test_pkt_access``::
50*8c061865SAndrey Ignatov
51*8c061865SAndrey Ignatov      % sudo bpf_inspect.py p | grep test_pkt_access
52*8c061865SAndrey Ignatov         650: BPF_PROG_TYPE_SCHED_CLS          test_pkt_access
53*8c061865SAndrey Ignatov         654: BPF_PROG_TYPE_TRACING            test_main                        linked:[650->25: BPF_TRAMP_FEXIT test_pkt_access->test_pkt_access()]
54*8c061865SAndrey Ignatov         655: BPF_PROG_TYPE_TRACING            test_subprog1                    linked:[650->29: BPF_TRAMP_FEXIT test_pkt_access->test_pkt_access_subprog1()]
55*8c061865SAndrey Ignatov         656: BPF_PROG_TYPE_TRACING            test_subprog2                    linked:[650->31: BPF_TRAMP_FEXIT test_pkt_access->test_pkt_access_subprog2()]
56*8c061865SAndrey Ignatov         657: BPF_PROG_TYPE_TRACING            test_subprog3                    linked:[650->21: BPF_TRAMP_FEXIT test_pkt_access->test_pkt_access_subprog3()]
57*8c061865SAndrey Ignatov         658: BPF_PROG_TYPE_EXT                new_get_skb_len                  linked:[650->16: BPF_TRAMP_REPLACE test_pkt_access->get_skb_len()]
58*8c061865SAndrey Ignatov         659: BPF_PROG_TYPE_EXT                new_get_skb_ifindex              linked:[650->23: BPF_TRAMP_REPLACE test_pkt_access->get_skb_ifindex()]
59*8c061865SAndrey Ignatov         660: BPF_PROG_TYPE_EXT                new_get_constant                 linked:[650->19: BPF_TRAMP_REPLACE test_pkt_access->get_constant()]
60*8c061865SAndrey Ignatov
61*8c061865SAndrey IgnatovIt can be seen that there is a program ``test_pkt_access``, id 650 and there
62*8c061865SAndrey Ignatovare multiple other tracing and ext programs attached to functions in
63*8c061865SAndrey Ignatov``test_pkt_access``.
64*8c061865SAndrey Ignatov
65*8c061865SAndrey IgnatovFor example the line::
66*8c061865SAndrey Ignatov
67*8c061865SAndrey Ignatov         658: BPF_PROG_TYPE_EXT                new_get_skb_len                  linked:[650->16: BPF_TRAMP_REPLACE test_pkt_access->get_skb_len()]
68*8c061865SAndrey Ignatov
69*8c061865SAndrey Ignatov, means that BPF program id 658, type ``BPF_PROG_TYPE_EXT``, name
70*8c061865SAndrey Ignatov``new_get_skb_len`` replaces (``BPF_TRAMP_REPLACE``) function ``get_skb_len()``
71*8c061865SAndrey Ignatovthat has BTF id 16 in BPF program id 650, name ``test_pkt_access``.
72*8c061865SAndrey Ignatov
73*8c061865SAndrey IgnatovGetting help:
74*8c061865SAndrey Ignatov
75*8c061865SAndrey Ignatov.. code-block:: none
76*8c061865SAndrey Ignatov
77*8c061865SAndrey Ignatov    % sudo bpf_inspect.py
78*8c061865SAndrey Ignatov    usage: bpf_inspect.py [-h] {prog,p,map,m} ...
79*8c061865SAndrey Ignatov
80*8c061865SAndrey Ignatov    drgn script to list BPF programs or maps and their properties
81*8c061865SAndrey Ignatov    unavailable via kernel API.
82*8c061865SAndrey Ignatov
83*8c061865SAndrey Ignatov    See https://github.com/osandov/drgn/ for more details on drgn.
84*8c061865SAndrey Ignatov
85*8c061865SAndrey Ignatov    optional arguments:
86*8c061865SAndrey Ignatov      -h, --help      show this help message and exit
87*8c061865SAndrey Ignatov
88*8c061865SAndrey Ignatov    subcommands:
89*8c061865SAndrey Ignatov      {prog,p,map,m}
90*8c061865SAndrey Ignatov        prog (p)      list BPF programs
91*8c061865SAndrey Ignatov        map (m)       list BPF maps
92*8c061865SAndrey Ignatov
93*8c061865SAndrey IgnatovCustomization
94*8c061865SAndrey Ignatov=============
95*8c061865SAndrey Ignatov
96*8c061865SAndrey IgnatovThe script is intended to be customized by developers to print relevant
97*8c061865SAndrey Ignatovinformation about BPF programs, maps and other objects.
98*8c061865SAndrey Ignatov
99*8c061865SAndrey IgnatovFor example, to print ``struct bpf_prog_aux`` for BPF program id 53077:
100*8c061865SAndrey Ignatov
101*8c061865SAndrey Ignatov.. code-block:: none
102*8c061865SAndrey Ignatov
103*8c061865SAndrey Ignatov    % git diff
104*8c061865SAndrey Ignatov    diff --git a/tools/bpf_inspect.py b/tools/bpf_inspect.py
105*8c061865SAndrey Ignatov    index 650e228..aea2357 100755
106*8c061865SAndrey Ignatov    --- a/tools/bpf_inspect.py
107*8c061865SAndrey Ignatov    +++ b/tools/bpf_inspect.py
108*8c061865SAndrey Ignatov    @@ -112,7 +112,9 @@ def list_bpf_progs(args):
109*8c061865SAndrey Ignatov             if linked:
110*8c061865SAndrey Ignatov                 linked = f" linked:[{linked}]"
111*8c061865SAndrey Ignatov
112*8c061865SAndrey Ignatov    -        print(f"{id_:>6}: {type_:32} {name:32} {linked}")
113*8c061865SAndrey Ignatov    +        if id_ == 53077:
114*8c061865SAndrey Ignatov    +            print(f"{id_:>6}: {type_:32} {name:32}")
115*8c061865SAndrey Ignatov    +            print(f"{bpf_prog.aux}")
116*8c061865SAndrey Ignatov
117*8c061865SAndrey Ignatov
118*8c061865SAndrey Ignatov     def list_bpf_maps(args):
119*8c061865SAndrey Ignatov
120*8c061865SAndrey IgnatovIt produces the output::
121*8c061865SAndrey Ignatov
122*8c061865SAndrey Ignatov    % sudo bpf_inspect.py p
123*8c061865SAndrey Ignatov     53077: BPF_PROG_TYPE_XDP                tw_xdp_policer
124*8c061865SAndrey Ignatov    *(struct bpf_prog_aux *)0xffff8893fad4b400 = {
125*8c061865SAndrey Ignatov            .refcnt = (atomic64_t){
126*8c061865SAndrey Ignatov                    .counter = (long)58,
127*8c061865SAndrey Ignatov            },
128*8c061865SAndrey Ignatov            .used_map_cnt = (u32)1,
129*8c061865SAndrey Ignatov            .max_ctx_offset = (u32)8,
130*8c061865SAndrey Ignatov            .max_pkt_offset = (u32)15,
131*8c061865SAndrey Ignatov            .max_tp_access = (u32)0,
132*8c061865SAndrey Ignatov            .stack_depth = (u32)8,
133*8c061865SAndrey Ignatov            .id = (u32)53077,
134*8c061865SAndrey Ignatov            .func_cnt = (u32)0,
135*8c061865SAndrey Ignatov            .func_idx = (u32)0,
136*8c061865SAndrey Ignatov            .attach_btf_id = (u32)0,
137*8c061865SAndrey Ignatov            .linked_prog = (struct bpf_prog *)0x0,
138*8c061865SAndrey Ignatov            .verifier_zext = (bool)0,
139*8c061865SAndrey Ignatov            .offload_requested = (bool)0,
140*8c061865SAndrey Ignatov            .attach_btf_trace = (bool)0,
141*8c061865SAndrey Ignatov            .func_proto_unreliable = (bool)0,
142*8c061865SAndrey Ignatov            .trampoline_prog_type = (enum bpf_tramp_prog_type)BPF_TRAMP_FENTRY,
143*8c061865SAndrey Ignatov            .trampoline = (struct bpf_trampoline *)0x0,
144*8c061865SAndrey Ignatov            .tramp_hlist = (struct hlist_node){
145*8c061865SAndrey Ignatov                    .next = (struct hlist_node *)0x0,
146*8c061865SAndrey Ignatov                    .pprev = (struct hlist_node **)0x0,
147*8c061865SAndrey Ignatov            },
148*8c061865SAndrey Ignatov            .attach_func_proto = (const struct btf_type *)0x0,
149*8c061865SAndrey Ignatov            .attach_func_name = (const char *)0x0,
150*8c061865SAndrey Ignatov            .func = (struct bpf_prog **)0x0,
151*8c061865SAndrey Ignatov            .jit_data = (void *)0x0,
152*8c061865SAndrey Ignatov            .poke_tab = (struct bpf_jit_poke_descriptor *)0x0,
153*8c061865SAndrey Ignatov            .size_poke_tab = (u32)0,
154*8c061865SAndrey Ignatov            .ksym_tnode = (struct latch_tree_node){
155*8c061865SAndrey Ignatov                    .node = (struct rb_node [2]){
156*8c061865SAndrey Ignatov                            {
157*8c061865SAndrey Ignatov                                    .__rb_parent_color = (unsigned long)18446612956263126665,
158*8c061865SAndrey Ignatov                                    .rb_right = (struct rb_node *)0x0,
159*8c061865SAndrey Ignatov                                    .rb_left = (struct rb_node *)0xffff88a0be3d0088,
160*8c061865SAndrey Ignatov                            },
161*8c061865SAndrey Ignatov                            {
162*8c061865SAndrey Ignatov                                    .__rb_parent_color = (unsigned long)18446612956263126689,
163*8c061865SAndrey Ignatov                                    .rb_right = (struct rb_node *)0x0,
164*8c061865SAndrey Ignatov                                    .rb_left = (struct rb_node *)0xffff88a0be3d00a0,
165*8c061865SAndrey Ignatov                            },
166*8c061865SAndrey Ignatov                    },
167*8c061865SAndrey Ignatov            },
168*8c061865SAndrey Ignatov            .ksym_lnode = (struct list_head){
169*8c061865SAndrey Ignatov                    .next = (struct list_head *)0xffff88bf481830b8,
170*8c061865SAndrey Ignatov                    .prev = (struct list_head *)0xffff888309f536b8,
171*8c061865SAndrey Ignatov            },
172*8c061865SAndrey Ignatov            .ops = (const struct bpf_prog_ops *)xdp_prog_ops+0x0 = 0xffffffff820fa350,
173*8c061865SAndrey Ignatov            .used_maps = (struct bpf_map **)0xffff889ff795de98,
174*8c061865SAndrey Ignatov            .prog = (struct bpf_prog *)0xffffc9000cf2d000,
175*8c061865SAndrey Ignatov            .user = (struct user_struct *)root_user+0x0 = 0xffffffff82444820,
176*8c061865SAndrey Ignatov            .load_time = (u64)2408348759285319,
177*8c061865SAndrey Ignatov            .cgroup_storage = (struct bpf_map *[2]){},
178*8c061865SAndrey Ignatov            .name = (char [16])"tw_xdp_policer",
179*8c061865SAndrey Ignatov            .security = (void *)0xffff889ff795d548,
180*8c061865SAndrey Ignatov            .offload = (struct bpf_prog_offload *)0x0,
181*8c061865SAndrey Ignatov            .btf = (struct btf *)0xffff8890ce6d0580,
182*8c061865SAndrey Ignatov            .func_info = (struct bpf_func_info *)0xffff889ff795d240,
183*8c061865SAndrey Ignatov            .func_info_aux = (struct bpf_func_info_aux *)0xffff889ff795de20,
184*8c061865SAndrey Ignatov            .linfo = (struct bpf_line_info *)0xffff888a707afc00,
185*8c061865SAndrey Ignatov            .jited_linfo = (void **)0xffff8893fad48600,
186*8c061865SAndrey Ignatov            .func_info_cnt = (u32)1,
187*8c061865SAndrey Ignatov            .nr_linfo = (u32)37,
188*8c061865SAndrey Ignatov            .linfo_idx = (u32)0,
189*8c061865SAndrey Ignatov            .num_exentries = (u32)0,
190*8c061865SAndrey Ignatov            .extable = (struct exception_table_entry *)0xffffffffa032d950,
191*8c061865SAndrey Ignatov            .stats = (struct bpf_prog_stats *)0x603fe3a1f6d0,
192*8c061865SAndrey Ignatov            .work = (struct work_struct){
193*8c061865SAndrey Ignatov                    .data = (atomic_long_t){
194*8c061865SAndrey Ignatov                            .counter = (long)0,
195*8c061865SAndrey Ignatov                    },
196*8c061865SAndrey Ignatov                    .entry = (struct list_head){
197*8c061865SAndrey Ignatov                            .next = (struct list_head *)0x0,
198*8c061865SAndrey Ignatov                            .prev = (struct list_head *)0x0,
199*8c061865SAndrey Ignatov                    },
200*8c061865SAndrey Ignatov                    .func = (work_func_t)0x0,
201*8c061865SAndrey Ignatov            },
202*8c061865SAndrey Ignatov            .rcu = (struct callback_head){
203*8c061865SAndrey Ignatov                    .next = (struct callback_head *)0x0,
204*8c061865SAndrey Ignatov                    .func = (void (*)(struct callback_head *))0x0,
205*8c061865SAndrey Ignatov            },
206*8c061865SAndrey Ignatov    }
207*8c061865SAndrey Ignatov
208*8c061865SAndrey Ignatov
209*8c061865SAndrey Ignatov.. Links
210*8c061865SAndrey Ignatov.. _drgn/doc: https://drgn.readthedocs.io/en/latest/
211*8c061865SAndrey Ignatov.. _drgn/tools: https://github.com/osandov/drgn/tree/master/tools
212*8c061865SAndrey Ignatov.. _bpf_inspect.py:
213*8c061865SAndrey Ignatov   https://github.com/osandov/drgn/blob/master/tools/bpf_inspect.py
214