Přeskočit na obsah
Magazín Chatujme.cz
Programování · čtení na 4 min

Pád ripgrepu ukazuje na chybu v jádře Linuxu. Model od OpenAI odmítl s laděním pomoct

Vývojář nahlásil 26. července, že ripgrep sestavený proti knihovně musl občas spadne při hledání v obřím stromu adresářů. O dva dny později zveřejnil analýzu, podle které za pádem stojí souběh ve správě paměti jádra Linuxu: vlákno přestane vidět bajt, který samo o deset instrukcí dřív zapsalo. Potvrzení od vývojářů jádra zatím není.

Plyšový tučňák Tux, maskot Linuxu
Tux, maskot Linuxu. Foto: Plodan, Wikimedia Commons (CC BY-SA 4.0)

Začalo to jako obyčejná stížnost na padající program. Za dva dny z ní byla analýza, která ukazuje jinam, než kde se hledalo: do správy paměti v jádře Linuxu.

Padalo jen sestavení proti musl

Daniel Fox Franke otevřel v neděli 26. července v repozitáři vyhledávacího nástroje ripgrep hlášení číslo 3494. Popsal v něm, že binárka pro cíl x86_64-unknown-linux-musl občas skončí signálem SIGSEGV, když prochází opravdu velký strom adresářů a běží přitom v mnoha vláknech. Pád nastal vždy na stejném místě: v kontrole vnitřní konzistence haldy uvnitř alokátoru mallocng, kam se program dostal přes obyčejné otevření adresáře.

Správce ripgrepu, který na GitHubu vystupuje pod jménem BurntSushi, se zeptal, jestli padají i jiné binárky. Franke odpověděl, že s ničím slinkovaným proti glibc pád vyvolat nedokázal a že stejně padá i starší ripgrep 15.1.0.

Vlákno přestane vidět, co samo napsalo

V úterý 28. července přibyl pod hlášením vzkaz, že králičí nora vede hlouběji a že podle Frankeho jde o chybu jádra. Doklady zveřejnil týž den v samostatném repozitáři pod licencí MIT-0.

Jádrem nálezu je pozorování, které na správně fungujícím počítači nemá jak nastat. Vlákno zapíše bajt na stránku paměti, kterou právě dostalo, a zhruba o deset strojových instrukcí později si totéž místo přečte – a najde nulu. Franke to změřil dvěma čteními naráz: to bezprostředně po zápisu hodnotu vidělo správně, to opožděné už ne.

Ten rozdíl je podstatný. Kdyby zápis jen nestihl dojít do paměti, procesor by ho pozdějšímu čtení podstrčil z vlastní fronty zápisů a vidělo by ho obojí. Když ho vidí jen to první, buď hodnotu mezitím přepsal někdo jiný, nebo se pod toutéž adresou vyměnila celá stránka paměti.

Pro druhou možnost mluví pohled do souboru /proc/self/pagemap v okamžiku neshody: stránka je hlášená jako přítomná a zapsaná, ale s číslem fyzického rámce 0. To je nulová stránka, kterou si jádro drží pro čtení z dosud nezapsané paměti.

Co pád zastaví a co ne

Tu první možnost, tedy přeteklé pole nebo použití uvolněné paměti, vyloučil Franke čtyřmi variantami knihovny musl. Liší se jen tím, co se se stránkami stane předtím, než do nich alokátor poprvé zapíše.

  • P0 bez úprav: 250 běhů, 4 pády.
  • P1 se dotkne předem všech stránek skupiny: 304 běhů, ani jeden pád.
  • CTRL se dotkne předem jen té jedné stránky, na které k chybě dochází: 305 běhů, ani jeden pád.
  • FAKEPF se zdrží stejně dlouho a stejně dlouho drží zámek alokátoru, ale zapisuje jinam: 308 běhů, 3 pády.

Podstatná je poslední položka. Kdyby pád způsobovalo zdržení nebo držení zámku, zmizel by i u varianty FAKEPF. Rozhoduje tedy to, jestli se na stránku sáhne dřív, než na ni alokátor poprvé zapíše – a to žádná chyba v programu ani v knihovně nevysvětlí.

Reprodukce vyšla na jednom stroji z pěti

Pád se dá vyvolat na povel, ale ne všude. Návod je v repozitáři: vygenerovat strom o zhruba 20 GiB v 1 841 862 souborech a nad ním pořád dokola pouštět rg s dvanácti vlákny. Pád přijde v průměru jednou za jednu až tři minuty; havarující běh trvá kolem 1,6 sekundy, čistý zhruba 7,6 sekundy.

Ze zkoušených pěti počítačů uspěl jen ten původní, Threadripper 9960X s jádrem 7.0.12 z openSUSE Tumbleweed. Threadripper 9970X téže generace s jádrem 6.19.10 pád nevydal, stejně jako EPYC 9575F a Xeon 678X s jádrem 6.8.0 a Ryzen AI MAX+ 395 s jádrem 6.18.35. „Pád sleduje verzi jádra, ne rodinu procesorů,“ uzavírá analýza tuhle část (přeloženo).

Kam ukazuje srovnání zdrojových kódů

Vysvětlení, ke kterému Franke došel, je souběh dvou cest v jádře. První je obsloužení výpadku stránky při zápisu do dosud nepoužité paměti; té dnes stačí zámek jedné oblasti a nemusí zamykat celou paměť procesu. Druhá je odmapování paměti voláním munmap, po kterém se všem procesorům rozešle žádost o zneplatnění záznamů v TLB, tedy v tabulce překladů adres uvnitř procesoru.

Zámek jedné oblasti proti odmapování nechrání. Když první cesta zveřejní nový záznam v tabulce stránek a druhá už mezitím touž adresu vyčistila, dorazí zneplatnění až po zveřejnění a smaže překlad, který právě vznikl.

Kde se to zhoršilo, hledal Franke porovnáním větví jádra. Cesta výpadku stránky je mezi verzemi 6.19 a 7.0 beze změny; změnil se úklid tabulek stránek při odmapování. Analýza jmenuje tři změny z ledna 2026, které ve verzi 7.0 jsou a v 6.19 nejsou: 4c640eb4181c, fb4ddf208511eda8c5e77622. Odpovídá to i rozdělení strojů výše.

Patří k tomu ale výhrada, kterou si Franke napsal sám: je to silná shoda, ne důkaz. Zdrojově nedoložil, že nová cesta opravdu strhne záznam, který výpadek stránky právě zveřejnil, a potvrzení nechává na revizi na straně jádra. Dotčené funkce se navíc od verze 7.0 po současný vývojový strom nezměnily, takže opravené to zatím není.

Model od OpenAI odmítl s laděním pomoct

Druhou polovinu příběhu popsal server The Register ve středu 29. července. Franke ladil chybu s pomocí jazykových modelů a u těch uzavřených narazil. Model GPT-5.6 Sol od OpenAI podle něj nespolupracoval, protože ho zastavil bezpečnostní klasifikátor; chybová hlášení ho posílala do firemního programu Enterprise Trusted Access. Modely Anthropicu prý ani nezkoušel, protože čekal totéž.

„Bezpečnostní klasifikátor OpenAI je pěkná otrava, když se snažíte vystopovat segfault,“ řekl Franke serveru The Register (přeloženo). Jinde dodal, že nástroj, který odmítá spolupracovat, je pro něj prostě rozbitý nástroj. Sama chyba se přitom poprvé ozvala v ripgrepu přibaleném k nástroji OpenAI Codex; ta binárka je podle Frankeho bajt po bajtu totožná s oficiálním vydáním 15.2.0.

Analýzu nakonec dotáhly modely s otevřenými váhami od čínských firem. Podle Frankeho přinesl klíčový průlom Kimi K3 od Moonshot AI a práci dokončil GLM 5.2 od Z’ai. Vyjádření OpenAI ani Anthropicu The Register neuvádí.

Stopy modelů jsou vidět i v dokladech samotných. Skript, který generuje testovací strom, je podle hlášení napsaný jazykovým modelem a jeden z commitů v repozitáři s analýzou se jmenuje „Human edit pass on AI prose“, tedy lidská redakce textu od modelu. Jestli takový kód patří do svobodných projektů, řeší chystané hlasování v Debianu.

Pro běžného uživatele z toho neplyne skoro nic: pád potřebuje binárku slinkovanou proti musl, skoro dva miliony souborů, dvanáct vláken a jednu konkrétní řadu jádra. Hodnota té analýzy je podle nás jinde. Ukazuje, kolik práce stojí dojít od „občas to spadne“ k pojmenování konkrétní části zdrojového kódu, a jak snadno by se u toho člověk zastavil na prvním podezřelém, tedy na alokátoru musl.

Zdroje: hlášení 3494 v repozitáři ripgrepurepozitář s analýzou včetně dat a záplat pro musl, o části s modely psal The Register. Názvy tří jmenovaných změn jsme ověřili v repozitáři jádra Linuxu.

Diskuse

Zatím tu nikdo nediskutuje. Můžete být první.

Napsat příspěvek

Diskutovat můžete i bez účtu. S registrací se ale příspěvek zveřejní hned a nemusíte pokaždé vyplňovat jméno. Účet už máte? Přihlaste se.

Nezveřejňujeme ho, slouží jen redakci.

Podporuje zápis Texy: **tučně**, *kurzíva*, odrážky, odkazy.

Dál k tématu

Programování

Turso přepsal SQLite do Rustu, nad stejným jádrem teď staví Postgres. Zatím jen ze zdroje

Databázový projekt Turso, který vznikl jako přepis SQLite do jazyka Rust, oznámil 16. července, že nad stejným jádrem staví i Postgres. Autoři to popisují jako „LLVM databází“: jedno jádro a víc jazykových rozhraní nad ním. Hotová databáze to zatím není – balíčky ke stažení neexistují a oznámení samo mluví o základu, ne o hotovém produktu.

Programování

Na kontrolu do Debianu čeká 36 balíčků, nejstarší tři týdny. Fronta je veřejně vidět

Než se nový balíček dostane do Debianu, musí někdo ručně ověřit, že jeho licence odpovídají pravidlům svobodného softwaru. Od letošního února má tahle fronta veřejný přehled, do kterého vidí kdokoli – dřív podle jeho autorů takový pohled zvenčí nebyl. Podíval jsem se, co v něm dnes stojí: 36 balíčků čeká na kontrolu, nejstarší z nich 21 dní, a za týden od 22. do 29. července jím prošlo 89 kontrol.

Programování

MCP se stal bezstavovým: zmizel úvodní handshake i hlavička se session

Protokol MCP, kterým jazykové modely sahají na cizí nástroje a data, vyšel 28. července v nové verzi. Podstatná změna je jediná, zato hluboká: zmizel úvodní handshake a hlavička s identifikátorem relace, takže každý požadavek nese všechno potřebné sám. Server si tedy nemusí nic pamatovat mezi voláními a provozovatel ho může postavit za obyčejný load balancer. Starší verze podle autorů fungují dál nejméně rok.

Programování

Unity ohlásilo verzi 7 na rok 2027. Slib, že se nic nerozbije, má výjimky

Unity ohlásilo 21. července na konferenci Unite Seoul plán sedmé generace svého herního nástroje. Beta má být v prosinci, vydání v prvním čtvrtletí 2027. Firma slibuje, že se projekty z šestky přenesou bez přestavby; její vlastní příručka k novému běhovému prostředí přitom vyjmenovává změny, které starý kód rozbijí.