1pahole(1) dwarves pahole(1)
2
3
4
6 pahole - Shows, manipulates data structure layout and pretty prints raw
7 data.
8
10 pahole [options] files
11
13 pahole shows data structure layouts encoded in debugging information
14 formats, DWARF, CTF and BTF being supported.
15
16 This is useful for, among other things: optimizing important data
17 structures by reducing its size, figuring out what is the field sitting
18 at an offset from the start of a data structure, investigating ABI
19 changes and more generally understanding a new codebase you have to
20 work with.
21
22 It also uses these structure layouts to pretty print data feed to its
23 standard input, e.g.:
24
25 $ pahole --header elf64_hdr --prettify /lib/modules/5.8.0-rc6+/build/vmlinux
26 {
27 .e_ident = { 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
28 .e_type = 2,
29 .e_machine = 62,
30 .e_version = 1,
31 .e_entry = 16777216,
32 .e_phoff = 64,
33 .e_shoff = 604653784,
34 .e_flags = 0,
35 .e_ehsize = 64,
36 .e_phentsize = 56,
37 .e_phnum = 5,
38 .e_shentsize = 64,
39 .e_shnum = 80,
40 .e_shstrndx = 79,
41 },
42 $
43
44 See the PRETTY PRINTING section for further examples and documentation.
45
46 The files must have associated debugging information. This information
47 may be inside the file itself, in ELF sections, or in another file.
48
49 One way to have this information is to specify the -g option to the
50 compiler when building it. When this is done the information will be
51 stored in an ELF section. For the DWARF debugging information format
52 this, adds, among others, the .debug_info ELF section. For CTF it is
53 found in just one ELF section, .SUNW_ctf. BTF comes in at least the
54 .BTF ELF section, and may come also with the .BTF.ext ELF section.
55
56 The debuginfo packages available in most Linux distributions are also
57 supported by pahole, where the debugging information is available in a
58 separate file.
59
60 By default, pahole shows the layout of all named structs in the files
61 specified.
62
63 If no files are specified, then it will look if the /sys/kernel/btf/vm‐
64 linux is present, using the BTF information present in it about the
65 running kernel, i.e. this works:
66
67 $ pahole list_head
68 struct list_head {
69 struct list_head * next; /* 0 8 */
70 struct list_head * prev; /* 8 8 */
71
72 /* size: 16, cachelines: 1, members: 2 */
73 /* last cacheline: 16 bytes */
74 };
75 $
76
77 If BTF is not present and no file is passed, then a vmlinux that
78 matches the build-id for the running kernel will be looked up in the
79 usual places, including where the kernel debuginfo packages put it,
80 looking for DWARF info instead.
81
82 See the EXAMPLES section for more usage suggestions.
83
84 It also pretty prints whatever is fed to its standard input, according
85 to the type specified, see the EXAMPLE session.
86
87 Use --count to state how many records should be pretty printed.
88
89
91 pahole supports the following options.
92
93
94 -C, --class_name=CLASS_NAMES
95 Show just these classes. This can be a comma separated list of
96 class names or file URLs (e.g.: file://class_list.txt)
97
98
99 -c, --cacheline_size=SIZE
100 Set cacheline size to SIZE bytes.
101
102
103 --sort Sort the output by type name, maybe this will grow to allow
104 sorting by other criteria.
105
106 This is mostly needed so that pretty printing from BTF and DWARF
107 can be comparable when using using multiple threads to load
108 DWARF data, when the order that the types in the compile units
109 is processed is not deterministic.
110
111
112 --compile
113 Generate compileable code, with all definitions for all types,
114 i.e.:
115
116 $ pahole --compile > vmlinux.h
117
118 Produces a header that can be included in a C source file and built. In
119 the example provided it will use the BTF info if available, otherwise
120 will look for a DWARF file matching the running kernel build-id.
121
122
123 --count=COUNT
124 Pretty print the first COUNT records from input.
125
126
127 --skip=COUNT
128 Skip COUNT input records.
129
130
131 -E, --expand_types
132 Expand class members. Useful to find in what member of inner
133 structs where an offset from the beginning of a struct is.
134
135
136 -F, --format_path
137 Allows specifying a list of debugging formats to try, in order.
138 Right now this includes "ctf" and "dwarf". The default format
139 path used is equivalent to "-F dwarf,ctf".
140
141
142 --hashbits=BITS
143 Allows specifying the number of bits for the debugging format
144 loader to use. The only one affected so far is the "dwarf" one,
145 its default now is 15, the maximum for it is now 21 bits. Tweak
146 it to see if it improves performance as the kernel evolves and
147 more types and functions have to be loaded.
148
149
150 --hex Print offsets and sizes in hexadecimal.
151
152
153 -r, --rel_offset
154 Show relative offsets of members in inner structs.
155
156
157 -p, --expand_pointers
158 Expand class pointer members.
159
160
161 -R, --reorganize
162 Reorganize struct, demoting and combining bitfields, moving mem‐
163 bers to remove alignment holes and padding.
164
165
166 -S, --show_reorg_steps
167 Show the struct layout at each reorganization step.
168
169
170 -i, --contains=CLASS_NAME
171 Show classes that contains CLASS_NAME.
172
173
174 -a, --anon_include
175 Include anonymous classes.
176
177
178 -A, --nested_anon_include
179 Include nested (inside other structs) anonymous classes.
180
181
182 -B, --bit_holes=NR_HOLES
183 Show only structs at least NR_HOLES bit holes.
184
185
186 -d, --recursive
187 Recursive mode, affects several other flags.
188
189
190 -D, --decl_exclude=PREFIX
191 exclude classes declared in files with PREFIX.
192
193
194 -f, --find_pointers_to=CLASS_NAME
195 Find pointers to CLASS_NAME.
196
197
198 -H, --holes=NR_HOLES
199 Show only structs with at least NR_HOLES holes.
200
201
202 -I, --show_decl_info
203 Show the file and line number where the tags were defined, if
204 available in the debugging information.
205
206
207 --skip_encoding_btf_vars
208 Do not encode VARs in BTF.
209
210
211 --skip_encoding_btf_decl_tag
212 Do not encode decl tags in BTF.
213
214
215 --skip_encoding_btf_enum64
216 Do not encode enum64 in BTF.
217
218
219 --skip_encoding_btf_type_tag
220 Do not encode type tags in BTF.
221
222
223 -j, --jobs=N
224 Run N jobs in parallel. Defaults to number of online processors
225 + 10% (like the 'ninja' build system) if no argument is speci‐
226 fied.
227
228
229 -J, --btf_encode
230 Encode BTF information from DWARF, used in the Linux kernel
231 build process when CONFIG_DEBUG_INFO_BTF=y is present, intro‐
232 duced in Linux v5.2. Used to implement features such as BPF CO-
233 RE (Compile Once - Run Everywhere).
234
235 See https://nakryiko.com/posts/bpf-portability-and-co-re/.
236
237
238 --btf_encode_detached=FILENAME
239 Same thing as -J/--btf_encode, but storing the raw BTF info into
240 a separate file.
241
242
243 --btf_encode_force
244 Ignore those symbols found invalid when encoding BTF.
245
246
247 --btf_base=PATH
248 Path to the base BTF file, for instance: vmlinux when encoding
249 kernel module BTF information. This may be inferred when asking
250 for a /sys/kernel/btf/MODULE, when it will be autoconfigured to
251 "/sys/kernel/btf/vmlinux".
252
253
254 --btf_gen_floats
255 Allow producing BTF_KIND_FLOAT entries in systems where the vm‐
256 linux DWARF information has float types.
257
258
259 --btf_gen_all
260 Allow using all the BTF features supported by pahole.
261
262
263 -l, --show_first_biggest_size_base_type_member
264 Show first biggest size base_type member.
265
266
267 -m, --nr_methods
268 Show number of methods of all classes, i.e. the number of func‐
269 tions have arguments that are pointers to a given class.
270
271 To get the number of methods for an specific class, please use:
272
273 $ pahole --nr_methods | grep -w sock
274 sock 1005
275 $
276
277 In the above example it used the BTF information in /sys/ker‐
278 nel/btf/vmlinux.
279
280
281 -M, --show_only_data_members
282 Show only the members that use space in the class layout. C++
283 methods will be suppressed.
284
285
286 -n, --nr_members
287 Show number of members.
288
289
290 -N, --class_name_len
291 Show size of classes.
292
293
294 -O, --dwarf_offset=OFFSET
295 Show tag with DWARF OFFSET.
296
297
298 -P, --packable
299 Show only structs that has holes that can be packed if members
300 are reorganized, for instance when using the --reorganize op‐
301 tion.
302
303
304 -P, --with_flexible_array
305 Show only structs that have a flexible array.
306
307
308 -q, --quiet
309 Be quieter.
310
311
312 -s, --sizes
313 Show size of classes.
314
315
316 -t, --separator=SEP
317 Use SEP as the field separator.
318
319
320 -T, --nr_definitions
321 Show how many times struct was defined.
322
323
324 -u, --defined_in
325 Show CUs where CLASS_NAME (-C) is defined.
326
327
328 --flat_arrays
329 Flatten arrays, so that array[10][2] becomes array[20]. Useful
330 when generating from both CTF/BTF and DWARF encodings for the
331 same binary for testing purposes.
332
333
334 --suppress_aligned_attribute
335 Suppress forced alignment markers, so that one can compare BTF
336 or CTF output, that don't have that info, to output from DWARF
337 >= 5.
338
339
340 --suppress_force_paddings
341
342 Suppress bitfield forced padding at the end of structs, as this
343 requires something like DWARF's DW_AT_alignment, so that one can
344 compare BTF or CTF output, that don't have that info.
345
346
347 --suppress_packed
348
349 Suppress the output of the inference of __attri‐
350 bute__((__packed__)), so that one can compare BTF or CTF output,
351 the inference algorithm uses things like DW_AT_alignment, so un‐
352 til it is improved to infer that as well for BTF, allow dis‐
353 abling this output.
354
355
356 --fixup_silly_bitfields
357 Converts silly bitfields such as "int foo:32" to plain "int
358 foo".
359
360
361 -V, --verbose
362 be verbose
363
364
365 --ptr_table_stats
366 Print statistics about ptr_table data structures, used to hold
367 all the types, tags and functions data structures, for develop‐
368 ment tuning of such tables, tuned for a typical 2021 vmlinux
369 file.
370
371
372 -w, --word_size=WORD_SIZE
373 Change the arch word size to WORD_SIZE.
374
375
376 -x, --exclude=PREFIX
377 Exclude PREFIXed classes.
378
379
380 -X, --cu_exclude=PREFIX
381 Exclude PREFIXed compilation units.
382
383
384 --lang=languages
385 Only process compilation units built from source code written in
386 the specified languages.
387
388 Supported languages:
389
390 ada83, ada95, bliss, c, c89, c99, c11, c++, c++03, c++11,
391 c++14, cobol74,
392 cobol85, d, dylan, fortran77, fortran90, fortran95, fortran03,
393 fortran08,
394 go, haskell, java, julia, modula2, modula3, objc, objc++,
395 ocaml, opencl,
396 pascal83, pli, python, renderscript, rust, swift, upc
397
398 The linux kernel, for instance, is written in 'c89' circa 2022,
399 use that in filters.
400
401 --lang_exclude=languages Don't process compilation units built
402 from source code written in the specified languages.
403
404 To filter out compilation units written in Rust, for instance,
405 use:
406
407 pahole -j --btf_encode --lang_exclude rust
408
409
410 -y, --prefix_filter=PREFIX
411 Include PREFIXed classes.
412
413
414 -z, --hole_size_ge=HOLE_SIZE
415 Show only structs with at least one hole greater or equal to
416 HOLE_SIZE.
417
418
419 --structs
420 Show only structs, all the other filters apply, i.e. to show
421 just the sizes of all structs combine --structs with --sizes,
422 etc.
423
424
425 --packed
426 Show only packed structs, all the other filters apply, i.e. to
427 show just the sizes of all packed structs combine --packed with
428 --sizes, etc.
429
430
431 --unions
432 Show only unions, all the other filters apply, i.e. to show just
433 the sizes of all unions combine --union with --sizes, etc.
434
435
436 --version
437 Show a traditional string version, i.e.: "v1.18".
438
439
440 --numeric_version
441 Show a numeric only version, suitable for use in Makefiles and
442 scripts where one wants to know what if the installed version
443 has some feature, i.e.: 118 instead of "v1.18".
444
445
446 --kabi_prefix=STRING
447 When the prefix of the string is STRING, treat the string as
448 STRING.
449
450
452 To enable the generation of debugging information in the Linux kernel
453 build process select CONFIG_DEBUG_INFO. This can be done using make
454 menuconfig by this path: "Kernel Hacking" -> "Compile-time checks and
455 compiler options" -> "Compile the kernel with debug info". Consider as
456 well enabling CONFIG_DEBUG_INFO_BTF by going thru the aforementioned
457 menuconfig path and then selecting "Generate BTF typeinfo". Most modern
458 distributions with eBPF support should come with that in all its ker‐
459 nels, greatly facilitating the use of pahole.
460
461 Many distributions also come with debuginfo packages, so just enable it
462 in your package manager repository configuration and install the ker‐
463 nel-debuginfo, or any other userspace program written in a language
464 that the compiler generates debuginfo (C, C++, for instance).
465
466
468 All the examples here use either /sys/kernel/btf/vmlinux, if present,
469 or lookup a vmlinux file matching the running kernel, using the build-
470 id info found in /sys/kernel/notes to make sure it matches.
471
472 Show a type:
473
474 $ pahole -C __u64
475 typedef long long unsigned int __u64;
476 $
477
478
479 Works as well if the only argument is a type name:
480
481 $ pahole raw_spinlock_t
482 typedef struct raw_spinlock raw_spinlock_t;
483 $
484
485
486 Multiple types can be passed, separated by commas:
487
488 $ pahole raw_spinlock_t,raw_spinlock
489 struct raw_spinlock {
490 arch_spinlock_t raw_lock; /* 0 4 */
491
492 /* size: 4, cachelines: 1, members: 1 */
493 /* last cacheline: 4 bytes */
494 };
495 typedef struct raw_spinlock raw_spinlock_t;
496 $
497
498
499 Types can be expanded:
500
501 $ pahole -E raw_spinlock
502 struct raw_spinlock {
503 /* typedef arch_spinlock_t */ struct qspinlock {
504 union {
505 /* typedef atomic_t */ struct {
506 int counter; /* 0 4 */
507 } val; /* 0 4 */
508 struct {
509 /* typedef u8 -> __u8 */ unsigned char locked; /* 0 1 */
510 /* typedef u8 -> __u8 */ unsigned char pending; /* 1 1 */
511 }; /* 0 2 */
512 struct {
513 /* typedef u16 -> __u16 */ short unsigned int locked_pending; /* 0 2 */
514 /* typedef u16 -> __u16 */ short unsigned int tail; /* 2 2 */
515 }; /* 0 4 */
516 }; /* 0 4 */
517 } raw_lock; /* 0 4 */
518
519 /* size: 4, cachelines: 1, members: 1 */
520 /* last cacheline: 4 bytes */
521 };
522 $
523
524
525 When decoding OOPSes you may want to see the offsets and sizes in hexa‐
526 decimal:
527
528 $ pahole --hex thread_struct
529 struct thread_struct {
530 struct desc_struct tls_array[3]; /* 0 0x18 */
531 long unsigned int sp; /* 0x18 0x8 */
532 short unsigned int es; /* 0x20 0x2 */
533 short unsigned int ds; /* 0x22 0x2 */
534 short unsigned int fsindex; /* 0x24 0x2 */
535 short unsigned int gsindex; /* 0x26 0x2 */
536 long unsigned int fsbase; /* 0x28 0x8 */
537 long unsigned int gsbase; /* 0x30 0x8 */
538 struct perf_event * ptrace_bps[4]; /* 0x38 0x20 */
539 /* --- cacheline 1 boundary (64 bytes) was 24 bytes ago --- */
540 long unsigned int debugreg6; /* 0x58 0x8 */
541 long unsigned int ptrace_dr7; /* 0x60 0x8 */
542 long unsigned int cr2; /* 0x68 0x8 */
543 long unsigned int trap_nr; /* 0x70 0x8 */
544 long unsigned int error_code; /* 0x78 0x8 */
545 /* --- cacheline 2 boundary (128 bytes) --- */
546 struct io_bitmap * io_bitmap; /* 0x80 0x8 */
547 long unsigned int iopl_emul; /* 0x88 0x8 */
548 mm_segment_t addr_limit; /* 0x90 0x8 */
549 unsigned int sig_on_uaccess_err:1; /* 0x98: 0 0x4 */
550 unsigned int uaccess_err:1; /* 0x98:0x1 0x4 */
551
552 /* XXX 30 bits hole, try to pack */
553 /* XXX 36 bytes hole, try to pack */
554
555 /* --- cacheline 3 boundary (192 bytes) --- */
556 struct fpu fpu; /* 0xc0 0x1040 */
557
558 /* size: 4352, cachelines: 68, members: 20 */
559 /* sum members: 4312, holes: 1, sum holes: 36 */
560 /* sum bitfield members: 2 bits, bit holes: 1, sum bit holes: 30 bits */
561 };
562 $
563
564
565 OK, I know the offset that causes its a 'struct thread_struct' and that
566 the offset is 0x178, so must be in that 'fpu' struct... No problem, ex‐
567 pand 'struct thread_struct' and combine with grep:
568
569 $ pahole --hex -E thread_struct | egrep '(0x178|struct fpu)' -B4 -A4
570 /* XXX 30 bits hole, try to pack */
571 /* XXX 36 bytes hole, try to pack */
572
573 /* --- cacheline 3 boundary (192 bytes) --- */
574 struct fpu {
575 unsigned int last_cpu; /* 0xc0 0x4 */
576
577 /* XXX 4 bytes hole, try to pack */
578
579 --
580 /* typedef u8 -> __u8 */ unsigned char alimit; /* 0x171 0x1 */
581
582 /* XXX 6 bytes hole, try to pack */
583
584 struct math_emu_info * info; /* 0x178 0x8 */
585 /* --- cacheline 6 boundary (384 bytes) --- */
586 /* typedef u32 -> __u32 */ unsigned int entry_eip; /* 0x180 0x4 */
587 } soft; /* 0x100 0x88 */
588 struct xregs_state {
589 $
590
591
592 Want to know where 'struct thread_struct' is defined in the kernel
593 sources?
594
595 $ pahole -I thread_struct | head -2
596 /* Used at: /sys/kernel/btf/vmlinux */
597 /* <0> (null):0 */
598 $
599
600
601 Not present in BTF, so use DWARF, takes a little bit longer, and assum‐
602 ing it finds the matching vmlinux file:
603
604 $ pahole -Fdwarf -I thread_struct | head -2
605 /* Used at: /home/acme/git/linux/arch/x86/kernel/head64.c */
606 /* <3333> /home/acme/git/linux/arch/x86/include/asm/processor.h:485 */
607 $
608
609
610 To find the biggest data structures in the Linux kernel:
611
612 $ pahole -s | sort -k2 -nr | head -5
613 cmp_data 290904 1
614 dec_datas 274520 1
615 cpu_entry_area 217088 0
616 pglist_data 172928 4
617 saved_cmdlines_buffer 131104 1
618 $
619
620 The second column is the size in bytes and the third is the number of
621 alignment holes in that structure.
622
623 Show data structures that have a raw spinlock and are related to the
624 RCU mechanism:
625
626 $ pahole --contains raw_spinlock_t --prefix rcu
627 rcu_node
628 rcu_data
629 rcu_state
630 $
631
632 To see that in context, combine it with grep:
633
634 $ pahole rcu_state | grep raw_spinlock_t -B1 -A5
635 /* --- cacheline 52 boundary (3328 bytes) --- */
636 raw_spinlock_t ofl_lock; /* 3328 4 */
637
638 /* size: 3392, cachelines: 53, members: 35 */
639 /* sum members: 3250, holes: 7, sum holes: 82 */
640 /* padding: 60 */
641 };
642 $
643
644
646 pahole can also use the data structure types to pretty print raw data
647 specified via --prettify. To consume raw data from the standard input,
648 just use '--prettify -'
649
650 It can also pretty print raw data from stdin according to the type
651 specified:
652
653 $ pahole -C modversion_info drivers/scsi/sg.ko
654 struct modversion_info {
655 long unsigned int crc; /* 0 8 */
656 char name[56]; /* 8 56 */
657
658 /* size: 64, cachelines: 1, members: 2 */
659 };
660 $
661 $ objcopy -O binary --only-section=__versions drivers/scsi/sg.ko versions
662 $
663 $ ls -la versions
664 -rw-rw-r--. 1 acme acme 7616 Jun 25 11:33 versions
665 $
666 $ pahole --count 3 -C modversion_info drivers/scsi/sg.ko --prettify versions
667 {
668 .crc = 0x8dabd84,
669 .name = "module_layout",
670 },
671 {
672 .crc = 0x45e4617b,
673 .name = "no_llseek",
674 },
675 {
676 .crc = 0xa23fae8c,
677 .name = "param_ops_int",
678 },
679 $
680 $ pahole --skip 1 --count 2 -C modversion_info drivers/scsi/sg.ko --prettify - < versions
681 {
682 .crc = 0x45e4617b,
683 .name = "no_llseek",
684 },
685 {
686 .crc = 0xa23fae8c,
687 .name = "param_ops_int",
688 },
689 $
690 This is equivalent to:
691
692 $ pahole --seek_bytes 64 --count 1 -C modversion_info drivers/scsi/sg.ko --prettify versions
693 {
694 .crc = 0x45e4617b,
695 .name = "no_llseek",
696 },
697 $
698
699 -C, --class_name=CLASS_NAME
700 Pretty print according to this class. Arguments may be passed to
701 it to affect how the pretty printing is performed, e.g.:
702
703
704 -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_EXIT)'
705
706 This would select the 'struct perf_event_header' as the type to use to
707 pretty print records states that the 'size' field in that struct should
708 be used to figure out the size of the record (variable sized records),
709 that the 'enum perf_event_type' should be used to pretty print the nu‐
710 meric value in perf_event_header->type and furthermore that it should
711 be used to heuristically look for structs with the same name (lower‐
712 case) of the enum entry that is converted from the type field, using it
713 to pretty print instead of the base 'perf_event_header' type. See the
714 PRETTY PRINTING EXAMPLES section below.
715
716 Furthermore the 'filter=' part can be used, so far with only the '=='
717 operator to filter based on the 'type' field and converting the string
718 'PERF_RECORD_EXIT' to a number according to type_enum.
719
720 The 'sizeof' arg defaults to the 'size' member name, if the name is
721 different, one can use
722 'sizeof=sz' form, ditto for 'type=other_member_name' field, that de‐
723 faults to 'type'.
724
725
727 Looking at the ELF header for a vmlinux file, using BTF, first lets
728 discover the ELF header type:
729
730 $ pahole --sizes | grep -i elf | grep -i _h
731 elf64_hdr 64 0
732 elf32_hdr 52 0
733 $
734
735 Now we can use this to show the first record from offset zero:
736
737 $ pahole -C elf64_hdr --count 1 --prettify /lib/modules/5.8.0-rc3+/build/vmlinux
738 {
739 .e_ident = { 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
740 .e_type = 2,
741 .e_machine = 62,
742 .e_version = 1,
743 .e_entry = 16777216,
744 .e_phoff = 64,
745 .e_shoff = 775923840,
746 .e_flags = 0,
747 .e_ehsize = 64,
748 .e_phentsize = 56,
749 .e_phnum = 5,
750 .e_shentsize = 64,
751 .e_shnum = 80,
752 .e_shstrndx = 79,
753 },
754 $
755
756 This is equivalent to:
757
758 $ pahole --header elf64_hdr --prettify /lib/modules/5.8.0-rc3+/build/vmlinux
759
760 The --header option also allows reference in other command line options
761 to fields in the header. This is useful when one wants to show multi‐
762 ple records in a file and the range where those fields are located is
763 specified in header fields, such as for perf.data files:
764
765 $ pahole --hex ~/bin/perf --header perf_file_header --prettify perf.data
766 {
767 .magic = 0x32454c4946524550,
768 .size = 0x68,
769 .attr_size = 0x88,
770 .attrs = {
771 .offset = 0xa8,
772 .size = 0x88,
773 },
774 .data = {
775 .offset = 0x130,
776 .size = 0x588,
777 },
778 .event_types = {
779 .offset = 0,
780 .size = 0,
781 },
782 .adds_features = { 0x16717ffc, 0, 0, 0 },
783 },
784 $
785
786 So to display the cgroups records in the perf_file_header.data section
787 we can use:
788
789 $ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_CGROUP)' --prettify perf.data
790 {
791 .header = {
792 .type = PERF_RECORD_CGROUP,
793 .misc = 0,
794 .size = 40,
795 },
796 .id = 1,
797 .path = "/",
798 },
799 {
800 .header = {
801 .type = PERF_RECORD_CGROUP,
802 .misc = 0,
803 .size = 48,
804 },
805 .id = 1553,
806 .path = "/system.slice",
807 },
808 {
809 .header = {
810 .type = PERF_RECORD_CGROUP,
811 .misc = 0,
812 .size = 48,
813 },
814 .id = 8,
815 .path = "/machine.slice",
816 },
817 {
818 .header = {
819 .type = PERF_RECORD_CGROUP,
820 .misc = 0,
821 .size = 128,
822 },
823 .id = 7828,
824 .path = "/machine.slice/libpod-42be8e8d4eb9d22405845005f0d04ea398548dccc934a150fbaa3c1f1f9492c2.scope",
825 },
826 {
827 .header = {
828 .type = PERF_RECORD_CGROUP,
829 .misc = 0,
830 .size = 88,
831 },
832 .id = 13,
833 .path = "/machine.slice/machine-qemu\x2d1\x2drhel6.sandy.scope",
834 },
835 $
836
837 For the common case of the header having a member that has the 'offset'
838 and 'size' members, it is possible to use this more compact form:
839
840 $ pahole ~/bin/perf --header=perf_file_header --range=data -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_CGROUP)' --prettify perf.data
841
842 This uses ~/bin/perf to get the type definitions, the defines 'struct
843 perf_file_header' as the header, then seeks '$header.data.offset' bytes
844 from the start of the file, and considers '$header.data.size' bytes
845 worth of such records. The filter expression may omit a common prefix,
846 in this case it could additionally be equivalently written as both
847 'filter=type==CGROUP' or the 'filter=' can also be omitted, getting as
848 compact as 'type==CGROUP':
849
850 If we look at:
851
852 $ pahole ~/bin/perf -C perf_event_header
853 struct perf_event_header {
854 __u32 type; /* 0 4 */
855 __u16 misc; /* 4 2 */
856 __u16 size; /* 6 2 */
857
858 /* size: 8, cachelines: 1, members: 3 */
859 /* last cacheline: 8 bytes */
860 };
861 $
862
863 And:
864
865 $ pahole ~/bin/perf -C perf_event_type
866 enum perf_event_type {
867 PERF_RECORD_MMAP = 1,
868 PERF_RECORD_LOST = 2,
869 PERF_RECORD_COMM = 3,
870 PERF_RECORD_EXIT = 4,
871 PERF_RECORD_THROTTLE = 5,
872 PERF_RECORD_UNTHROTTLE = 6,
873 PERF_RECORD_FORK = 7,
874 PERF_RECORD_READ = 8,
875 PERF_RECORD_SAMPLE = 9,
876 PERF_RECORD_MMAP2 = 10,
877 PERF_RECORD_AUX = 11,
878 PERF_RECORD_ITRACE_START = 12,
879 PERF_RECORD_LOST_SAMPLES = 13,
880 PERF_RECORD_SWITCH = 14,
881 PERF_RECORD_SWITCH_CPU_WIDE = 15,
882 PERF_RECORD_NAMESPACES = 16,
883 PERF_RECORD_KSYMBOL = 17,
884 PERF_RECORD_BPF_EVENT = 18,
885 PERF_RECORD_CGROUP = 19,
886 PERF_RECORD_TEXT_POKE = 20,
887 PERF_RECORD_MAX = 21,
888 };
889 $
890
891 And furthermore:
892
893 $ pahole ~/bin/perf -C perf_record_cgroup
894 struct perf_record_cgroup {
895 struct perf_event_header header; /* 0 8 */
896 __u64 id; /* 8 8 */
897 char path[4096]; /* 16 4096 */
898
899 /* size: 4112, cachelines: 65, members: 3 */
900 /* last cacheline: 16 bytes */
901 };
902 $
903
904 Then we can see how the perf_event_header.type could be converted from
905 a __u32 to a string (PERF_RECORD_CGROUP). If we remove that
906 type_enum=perf_event_type, we will lose the conversion of 'struct
907 perf_event_header' to the more descriptive 'struct perf_record_cgroup',
908 and also the beautification of the header.type field:
909
910 $ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,filter=type==19)' --prettify perf.data
911 {
912 .type = 19,
913 .misc = 0,
914 .size = 40,
915 },
916 {
917 .type = 19,
918 .misc = 0,
919 .size = 48,
920 },
921 {
922 .type = 19,
923 .misc = 0,
924 .size = 48,
925 },
926 {
927 .type = 19,
928 .misc = 0,
929 .size = 128,
930 },
931 {
932 .type = 19,
933 .misc = 0,
934 .size = 88,
935 },
936 $
937
938 Some of the records are not found in 'type_enum=perf_event_type' so
939 some of the records don't get converted to a type that fully shows its
940 contents. For perf we know that those are in another enumeration, 'enum
941 perf_user_event_type', so, for these cases, we can create a 'virtual
942 enum', i.e. the sum of two enums and then get all those entries decoded
943 and properly casted, first few records with just 'enum
944 perf_event_type':
945
946 $ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type)' --count 4 --prettify perf.data
947 {
948 .type = 79,
949 .misc = 0,
950 .size = 32,
951 },
952 {
953 .type = 73,
954 .misc = 0,
955 .size = 40,
956 },
957 {
958 .type = 74,
959 .misc = 0,
960 .size = 32,
961 },
962 {
963 .header = {
964 .type = PERF_RECORD_CGROUP,
965 .misc = 0,
966 .size = 40,
967 },
968 .id = 1,
969 .path = "/",
970 },
971 $
972
973 Now with both enumerations, i.e. with
974 'type_enum=perf_event_type+perf_user_event_type':
975
976 $ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type+perf_user_event_type)' --count 5 --prettify perf.data
977 {
978 .header = {
979 .type = PERF_RECORD_TIME_CONV,
980 .misc = 0,
981 .size = 32,
982 },
983 .time_shift = 31,
984 .time_mult = 1016803377,
985 .time_zero = 435759009518382,
986 },
987 {
988 .header = {
989 .type = PERF_RECORD_THREAD_MAP,
990 .misc = 0,
991 .size = 40,
992 },
993 .nr = 1,
994 .entries = 0x50 0x7e 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00,
995 },
996 {
997 .header = {
998 .type = PERF_RECORD_CPU_MAP,
999 .misc = 0,
1000 .size = 32,
1001 },
1002 .data = {
1003 .type = 1,
1004 .data = "",
1005 },
1006 },
1007 {
1008 .header = {
1009 .type = PERF_RECORD_CGROUP,
1010 .misc = 0,
1011 .size = 40,
1012 },
1013 .id = 1,
1014 .path = "/",
1015 },
1016 {
1017 .header = {
1018 .type = PERF_RECORD_CGROUP,
1019 .misc = 0,
1020 .size = 48,
1021 },
1022 .id = 1553,
1023 .path = "/system.slice",
1024 },
1025 $
1026
1027 It is possible to pass multiple types, one has only to make sure they
1028 appear in the file in sequence, i.e. for the perf.data example, see the
1029 perf_file_header dump above, one can print the perf_file_attr structs
1030 in the header attrs range, then the perf_event_header in the data range
1031 with the following command:
1032
1033 pahole ~/bin/perf --header=perf_file_header -C 'perf_file_attr(range=attrs),perf_event_header(range=data,sizeof,type,type_enum=perf_event_type+perf_user_event_type)' --prettify perf.data
1034
1035
1037 eu-readelf(1), readelf(1), objdump(1).
1038
1039 https://www.kernel.org/doc/ols/2007/ols2007v2-pages-35-44.pdf.
1040
1042 pahole was written and is maintained by Arnaldo Carvalho de Melo
1043 <acme@kernel.org>.
1044
1045 Thanks to Andrii Nakryiko and Martin KaFai Lau for providing the BTF
1046 encoder and improving the codebase while making sure the BTF encoder
1047 works as needed to be used in encoding the Linux kernel .BTF section
1048 from the DWARF info generated by gcc. For that Andrii wrote a BTF dedu‐
1049 plicator in libbpf that is used by pahole.
1050
1051 Also thanks to Conectiva, Mandriva and Red Hat for allowing me to work
1052 on these tools.
1053
1054 Please send bug reports to <dwarves@vger.kernel.org>.
1055
1056 No subscription is required.
1057
1058
1059
1060dwarves January 16, 2020 pahole(1)