Skip to content

pahole - Struct Layout & Cache-Line Analysis Cheatsheet

pahole - Struct Layout & Cache-Line Analysis Cheatsheet

pahole (“poke-a-hole”) reads DWARF or BTF debug information and prints the actual memory layout of C structures — where each field sits, how much padding the compiler inserted, and how many cache lines the struct spans. Compilers pad structs to satisfy alignment, and a carelessly-ordered struct can waste dozens of bytes and straddle extra cache lines. On hot data structures that translates directly into cache misses. pahole makes the waste visible so you can reorder fields and shrink it.

Installation

PlatformCommand
Debian/Ubuntusudo apt install dwarves
Fedora/RHELsudo dnf install dwarves
Arch Linuxsudo pacman -S pahole
From sourcebuild the dwarves project
Verifypahole --version

Your binary must be built with debug info (-g). Stripped binaries have nothing for pahole to read.

Basic Usage

CommandDescription
pahole ./myprogramShow all structs in the binary
pahole -C mystruct ./myprogramOne specific struct
pahole -C task_struct /sys/kernel/btf/vmlinuxKernel struct via BTF
pahole --sizes ./myprogramList struct sizes
pahole -H 1 ./myprogramOnly structs with ≥1 hole

Reading the Output

struct example {
        char                       flag;                 /*     0     1 */

        /* XXX 7 bytes hole, try to pack */

        long int                   counter;              /*     8     8 */
        char                       name[16];             /*    16    16 */
        int                        id;                   /*    32     4 */

        /* XXX 4 bytes hole, try to pack */

        void *                     ptr;                  /*    40     8 */

        /* size: 48, cachelines: 1, members: 5 */
        /* sum members: 37, holes: 2, sum holes: 11 */
};
AnnotationMeaning
/* offset size */Byte offset and size of each field
XXX N bytes holePadding the compiler inserted
size:Total struct size
cachelines:How many 64-byte lines it spans
sum holes:Total wasted bytes
last cacheline:Bytes used in the final line

Finding Waste Across a Codebase

CommandFinds
pahole -H 1 ./binStructs with holes
pahole --nr_members ./binSorted by member count
pahole -c 2 ./binStructs spanning ≥2 cache lines
pahole -E ./binExpand nested structs inline
pahole -a ./binShow alignment/packing details
# Which structs waste the most memory to padding?
pahole -H 8 ./myprogram | head -50

Fixing Layout

The standard fix is ordering fields from largest to smallest alignment:

/* Before: 48 bytes, 11 wasted */
struct bad  { char flag; long counter; char name[16]; int id; void *ptr; };

/* After: 40 bytes, 0 wasted */
struct good { long counter; void *ptr; char name[16]; int id; char flag; };
TechniqueEffect
Order by descending alignmentEliminates most holes
Group hot fields togetherKeeps them in one cache line
Split cold fields into a second structHot data stays dense
__attribute__((packed))Removes padding — but may slow unaligned access
BitfieldsPack small flags

pahole can even suggest a reordering with --reorganize:

pahole --reorganize -C mystruct ./myprogram

Kernel Work (BTF)

CommandPurpose
pahole -C task_struct /sys/kernel/btf/vmlinuxInspect a live kernel struct
pahole -J vmlinuxGenerate BTF from DWARF
pahole --btf_encodeBTF encoding for eBPF tooling

BTF generation is why dwarves is a kernel build dependency — eBPF’s CO-RE relies on it.

When This Matters

SituationImpact
Millions of instances of a structMemory savings scale linearly
Hot loop touching struct fieldsFewer cache lines = fewer misses
Network/disk serializationSmaller structs, less I/O
Embedded/constrained memoryEvery byte counts
A struct used twiceDo not bother
ToolAnswers
paholeHow is this struct laid out, and where is the waste?
perfAm I actually cache-missing?
valgrind (cachegrind)Simulated cache behavior
heaptrackWhere does heap memory go?

Use perf to confirm cache misses are your bottleneck, then pahole to fix the layout causing them.

Resources