Discovering a subtle source of binary bloat in Rust


After adding a log buffer to the kernel of my OS I noticed the binary size increased by a substantial amount. More interestingly, it increased by roughly the size of the buffer, implying the compiler was putting the buffer in the .data section instead of .bss.

The culprit is the following structure:

static LOG: SpinLock<Log> = SpinLock::new(Log { buf: [0; SIZE], head: 0, readers: Vec::new() });

Try to guess what the issue is :P

Vec uses a NonNull internally to point to an allocation. However, as the name implies, NonNull cannot be null, so instead it has some non-zero value instead (i.e. it dangles). Because of this the Log structure isn’t all zeroes and the compiler is forced to put it in the .data section.

There’s probably a few of these instances in many codebases, so it’s worth investigating when attempting to reduce binary bloat.