Skrev en parser som läser den verkliga C‑headern på 7 308 rader och verifierar varje anropsställe, varje enum‑konstant och att varje klass som äger en pekare är final, efter att en handskriven platshållarheader hade låtit anrop till tre borttagna funktioner kompilera, länka och krascha.
Arbetet utfört: september 2026
7,308 rader C‑header, lästa i stället för antagna
Situation. Tidigt i projektet representerades C‑gränssnittet av en handskriven headerfil som beskrev de funktioner som applikationen förväntade sig. Den headerfilen kompilerade, applikationen länkades, och anrop till tre funktioner som inte längre fanns i kärnan kom ända fram till att anropas och kraschade. Både kompilatorn och länkaren hade nöjt sig med en beskrivning av biblioteket i stället för biblioteket självt, och glappet visade sig först vid körning.
Uppgift. Den riktiga headerfilen — 7 308 rader och 268 deklarationer — måste bli auktoriteten, och varje användning av den i Swift‑koden måste verifieras mot den automatiskt i stället för genom granskning.
Handling. Kontrollen är en parser som läser den faktiska headerfilen från uppströms och bygger upp mängden av de funktioner, enum‑konstanter och typer den deklarerar, och sedan läser Swift‑källkoden och slår upp varje anropsställe och varje konstantreferens mot den mängden. Ett anrop till en funktion som headerfilen inte deklarerar får bygget att fallera. En referens till en enum‑konstant som har bytt namn får bygget att fallera. Det aktuella antalet är 132 av de 268 deklarationerna som refereras, och att veta vilka 136 som inte används är i sig användbart, eftersom det säger exakt hur stor del av kärnan som klienten inte har nått. Parsern upprätthåller också en regel som kompilatorn inte kan: varje Swift‑klass som äger en pekare in i kärnan måste vara final. En klass som äger en pekare och inte är final kan ärvas, och en subklass som åsidosätter deinitieringen eller lägger till en egen livslängd ändrar när pekaren frigörs — en use‑after‑free utan ett enda unsafe‑nyckelord i närheten. Regeln kontrolleras med namn över hela trädet.
Resultat. Den feltyp som orsakade den ursprungliga kraschen kan inte återkomma, eftersom en inaktuell referens nu är ett byggfel i stället för ett körtidsfel. Begränsningen är att parsern förstår headerfilens deklarationer men inte dess semantik: den bevisar att en funktion med ett matchande namn finns, och en funktion vars betydelse eller ägarskapsregel har ändrats uppströms medan signaturen behållits passerar utan anmärkning.
Se tillbaka på Stoppade en applikation som fyllde minnet med 41 MB i sekunden — uppmätt 111 GB komprimerade sidor på en maskin med 36 GB — genom att begränsa varje händelseström, prenumerera per händelsetyp och sätta en hastighetsbudget på loggningen, vilket tog ned 610 996 loggrader till 1 411. Läs vidare: Tog i bruk den hälft av meddelandekärnan som applikationen aldrig hade använt — överföring av säkerhetskopior, försvinnande meddelanden, redigering och omsändning av meddelanden, verifierade inbjudningar, proxyer och krypteringspolicy — och körde varje test mot det riktiga biblioteket utan mockar. Eller ta en titt på hela portföljen.
En del av en längre historik — och den finns i sin helhet här.
Varje post är skriven på samma sätt: situationen, uppgiften, vad vi gjorde och vad som förändrades.