Nick Desaulniers

The enemy's gate is down

Mar 10, 2023 - 8 minute read - opinion

USPS as an ISP

While on a hike with colleagues, one asked a thought provoking question: Should the United States Post Service (USPS) operate as an Internet Service Provider (ISP)? This post is an opinion piece playing with that idea; here are my thoughts. It’s far from a hot take, and has been discussed before.

Article 1 Section 8 of the United States Constitution states: “The Congress shall have Power…To establish Post Offices and post Roads;”

Mar 10, 2023 - 8 minute read - ARM

Disambiguating Arm, Arm ARM, Armv9, ARM9, ARM64, AArch64, A64, A78, ...

If you’re new to the Arm ecosystem, consider this a quick primer on terms you likely have seen before but might have questions about.

The Arm architecture is a family of Reduced Instruction Set Architectures (RISC) with simple addressing modes. Data processing is done on register operands otherwise relying on loads and stores to move data into and out of registers.

Arm Limited, the British company, stewards the Arm architecture.

ARM is a legacy acronym for Acorn RISC Machine, then Advanced RISC Machines. As we’ll see, with new advancements in the architecture, previous terms for things sometimes get renamed.

Feb 1, 2023 - 5 minute read - Open Source Software security

Forking is not free; the hidden costs

The Open Source software development model is a powerful approach to collaboratively iterating on a shared solution to a common problem. Rather than competitors duplicating effort to come up with multiple suboptimal solutions, they can collaborate together to build something greater.

Forking is the term used to denote making a copy of a codebase. The copy, known as a “fork” is used as a starting point for work that may be contributed back to the original maintainers; the canonical “upstream” from which we derive our “downstream” clone. These copies share a similar origin point; think of all of the things in life that share a similar origin, but due to various factors have diverged slightly over time in assorted measures.

Jan 27, 2023 - 8 minute read - compilers llvm

Critical Edge Splitting

A maximal length sequence of branch-free code that terminates with a branch or jump is referred to as a basic block.

A basic block that branches to another forms an edge in the Control Flow Graph (CFG).

The initial basic block starting an edge is the predecessor; it precedes and is succeeded by the successor basic block.

An edge between basic blocks is considered a critical edge if the predecessor has multiple successors, and the successor has multiple predecessors.

Jan 20, 2023 - 8 minute read - debugging

Debugging -Wframe-larger-than=

Unless work is done per architecture to implement HAVE_ARCH_VMAP_STACK / CONFIG_VMAP_STACK, the Linux kernel defaults to two pages worth of stack per thread.


Note: on many contemporary systems the page size is 4KiB, but this is actually configurable for many architectures. The trade offs probably require a separate post. If you see code that checks for alignment via bitwise tricks like addr & 4095 == 0 without checking sysconf(_SC_PAGESIZE) it is perhaps a red flag for code that might be to reused on different systems.

Apr 6, 2020 - 19 minute read - asm clang asm goto linux llvm

Off by Two

“War stories” in programming are entertaining tales of truly evil bugs that kept you up at night. Inspired by posts like My Hardest Bug Ever, Debugging an evil Go runtime bug, and others from /r/TalesFromDebugging, I wanted to share with you one of my favorites from recent memory. Recent work has given me much fulfilment and a long list of truly awful bugs to recount. My blog has been quieter than I would have liked; hopefully I can find more time to document some of these, maybe in series form. May I present to you episode I; “Off by Two.”

May 12, 2019 - 6 minute read - C C++ syntax

f() vs f(void) in C vs C++

TL;DR

Prefer f(void) in C to potentially save a 2B instruction per function call when targeting x86_64 as a micro-optimization. -Wstrict-prototypes can help. Doesn’t matter for C++.

The Problem

While messing around with some C code in godbolt Compiler Explorer, I kept noticing a particular funny case. It seemed with my small test cases that sometimes function calls would zero out the return register before calling a function that took no arguments, but other times not. Upon closer inspection, it seemed like a difference between function definitions, particularly f() vs f(void). For example, the following C code:

Jan 18, 2019 - 5 minute read - C C++ debugging c-reduce linux llvm

Finding Compiler Bugs With C-Reduce

Support for a long awaited GNU C extension, asm goto, is in the midst of landing in Clang and LLVM. We want to make sure that we release a high quality implementation, so it’s important to test the new patches on real code and not just small test cases. When we hit compiler bugs in large source files, it can be tricky to find exactly what part of potentially large translation units are problematic. In this post, we’ll take a look at using C-Reduce, a multithreaded code bisection utility for C/C++, to help narrow done a reproducer for a real compiler bug (potentially; in a patch that was posted, and will be fixed before it can ship in production) from a real code base (the Linux kernel). It’s mostly a post to myself in the future, so that I can remind myself how to run C-reduce on the Linux kernel again, since this is now the third real compiler bug it’s helped me track down.

Oct 24, 2018 - 6 minute read - gdb linux qemu vm debugging

Booting a Custom Linux Kernel in QEMU and Debugging It With GDB

Typically, when we modify a program, we’d like to run it to verify our changes. Before booting a compiled Linux kernel image on actual hardware, it can save us time and potential headache to do a quick boot in a virtual machine like QEMU as a sanity check. If your kernel boots in QEMU, it’s not a guarantee it will boot on metal, but it is a quick assurance that the kernel image is not completely busted. Since I finally got this working, I figured I’d post the built up command line arguments (and error messages observed) for future travelers. Also, QEMU has more flags than virtually any other binary I’ve ever seen (other than a google3 binary; shots fired), and simply getting it to print to the terminal is 3/4 the battle. If I don’t write it down now, or lose my shell history, I’ll probably forget how to do this.

Jun 2, 2018 - 3 minute read - C linux ccache

Speeding Up Linux Kernel Builds With ccache

ccache, the compiler cache, is a fantastic way to speed up build times for C and C++ code that I previously recommended. Recently, I was playing around with trying to get it to speed up my Linux kernel builds, but wasn’t seeing any benefit. Usually when this happens with ccache, there’s something non-deterministic about the builds that prevents cache hits.

Turns out someone asked this exact question on the ccache mailing list back in 2014, and a teammate from my Android days supposed a timestamp was the culprit. That, and this LKML post from the KBUILD maintainer in 2011 about determinism helped me find commit 87c94bfb8ad35 (“kbuild: override build timestamp & version”) that introduced manually overriding part of the version string that contains the build timestamp that can be seen from: