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