Dalam dunia pengkomputeran berskala tinggi, walaupun pepijat yang paling jarang berlaku menjadi tidak dapat dielakkan apabila anda memproses beratus-ratus juta permintaan HTTP. Jurutera Cloudflare baru-baru ini menghadapi satu masalah sukar seperti ini - kegagalan misteri yang muncul secara rawak pada infrastruktur ARM64 mereka. Apa yang bermula sebagai panik sekali-sekala akhirnya mendedahkan dirinya sebagai pepijat asas dalam penyusun ARM64 Go, menunjukkan bagaimana kerumitan perisian moden boleh menyembunyikan isu-isu halus tetapi kritikal.
![]() |
|---|
| Catatan blog ini membincangkan penemuan pepijat asas dalam pengkompil ARM64 Go, isu kritikal yang dihadapi oleh jurutera Cloudflare semasa memproses berjuta-juta permintaan HTTP |
Hantu dalam Mesin
Selama beberapa minggu, jurutera Cloudflare memerhatikan kesalahan segmentasi pelik dan panik maut yang berlaku pada pelayan ARM64 mereka. Kegagalan ini amat membingungkan kerana ia kelihatan benar-benar rawak - muncul tanpa corak yang jelas dan hanya menjejaskan peratusan kecil trafik besar yang mengalir melalui rangkaian global Cloudflare. Penyiasatan awal menunjuk ke arah kerosakan memori, tetapi punca akar tetap sukar difahami walaupun dengan usaha penyahpepijatan yang meluas.
Masalah ini ditunjukkan sebagai kesalahan segmentasi semasa operasi pengumpulan sampah dan pengembangan timbunan. Jurutera menyedari bahawa kegagalan ini secara konsisten berlaku semasa premptif async - mekanisme Go untuk mengganggu goroutine yang berjalan lama untuk mengekalkan penjadualan yang adil. Petunjuk ini menjadi benang pertama dalam apa yang akan menjadi perjalanan penyahpepijatan yang kompleks.
Satu perkara yang sering terlepas pandang adalah betapa sukarnya untuk mengesyaki penyusun sebagai punca akar. Kebanyakan jurutera membuang masa berjam-jam mengejar pepijat dalam kod mereka sendiri kerana kita dilatih untuk mempercayai alat kita.
Mendedahkan Keadaan Perlumbaan
Kejayaan berlaku apabila jurutera menyedari kegagalan berlaku semasa tetingkap yang sangat spesifik - apabila runtime Go melakukan premptif ke atas goroutine di tengah-tengah pelarasan penunjuk timbunan. Pada seni bina ARM64, pelarasan penunjuk timbunan besar kadangkala dibahagikan kepada berbilang arahan oleh pemasang Go. Jika premptif async berlaku antara arahan yang terpisah ini, ia meninggalkan penunjuk timbunan dalam keadaan yang tidak konsisten.
Ini mewujudkan keadaan perlumbaan di mana pengumpulan sampah akan cuba mengembangkan timbunan dengan penunjuk yang tidak sah, membawa kepada kesalahan segmentasi. Pepijat ini amat halus kerana ia hanya menjejaskan fungsi dengan bingkai timbunan lebih besar daripada 4KB, dan hanya pada seni bina ARM64 di mana arahan panjang tetap kadangkala memerlukan operasi kompleks dipecahkan kepada berbilang langkah.
Perbincangan komuniti menekankan bagaimana pepijat jenis ini mewakili masalah klasik dalam pengaturcaraan sistem. Beberapa pengulas menyatakan pengalaman serupa dengan pepijat penyusun sepanjang kerjaya mereka, menekankan bagaimana skala dan perbezaan seni bina boleh mendedahkan isu yang kekal tersembunyi dalam kebanyakan persekitaran pembangunan.
Butiran Teknikal Utama:
- Seni bina: ARM64 (set arahan panjang tetap)
- Masalah: Pelarasan penunjuk timbunan dipecahkan kepada berbilang arahan
- Kesan: Penunjuk timbunan tidak sah semasa pengumpulan sampah
- Penyelesaian: Gunakan daftar sementara untuk kemas kini penunjuk timbunan secara atom
- Kaedah pengesanan: Analisis corak kerosakan pada skala besar-besaran (beratus juta permintaan)
Pembaikan dan Implikasinya
Jurutera Cloudflare membangunkan penghasil semula minimum yang menunjukkan pepijat tanpa sebarang kebergantungan luaran. Ini membolehkan mereka mengesahkan isu tersebut memang berada dalam runtime Go dan bukannya kod aplikasi mereka. Pembaikan melibatkan pengubahsuaian bagaimana penyusun Go mengendalikan pelarasan timbunan besar pada ARM64 - memastikan pengubahsuaian penunjuk timbunan berlaku secara atomik dalam satu arahan tunggal dan bukannya terpisah merentasi berbilang operasi.
Pepijat ini cepat ditangani oleh pasukan Go dan dibaiki dalam versi 1.21.3, 1.20.10, dan 1.19.13. Penyelesaiannya menghalang keadaan perlumbaan dengan menggunakan daftar sementara untuk membina nilai ofset besar, kemudian mengaplikasikannya kepada penunjuk timbunan dalam satu operasi yang tidak boleh dibahagikan. Ini memastikan goroutine boleh diprampta sebelum atau selepas pengubahsuaian penunjuk timbunan, tetapi tidak pernah semasa fasa pelarasan kritikal.
Ahli komuniti membincangkan implikasi yang lebih luas pepijat sedemikian, dengan beberapa orang menyatakan bahawa ini menekankan kepentingan memahami bahasa pemasangan walaupun dalam persekitaran pengaturcaraan peringkat tinggi. Yang lain menegaskan bahawa isu serupa telah muncul sepanjang sejarah pengkomputeran, sering berkaitan dengan pengubahsuaian penunjuk timbunan tidak atomik merentasi seni bina yang berbeza.
Versi Go yang Terjejas dan Pembaikan:
- Go 1.19.x: Diperbaiki dalam 1.19.13
- Go 1.20.x: Diperbaiki dalam 1.20.10
- Go 1.21.x: Diperbaiki dalam 1.21.3
- Punca masalah: Pelarasan penunjuk timbunan bukan atom pada ARM64
- Syarat pencetus: Preemption tak segerak antara arahan split untuk bingkai timbunan >4KB
Pengajaran untuk Pembangunan Perisian Moden
Kejadian ini menggariskan beberapa pengajaran penting untuk operasi perisian berskala besar. Pertama, ia menunjukkan nilai dasar penyiasatan kegagalan yang menyeluruh - Cloudflare mewajibkan penyiasatan setiap kegagalan setelah sebelum ini belajar bahawa kegagalan yang tidak dapat dijelaskan boleh menjadi tanda amaran awal isu serius. Kedua, ia menunjukkan bagaimana perbezaan seni bina penting - pepijat yang tidak pernah muncul pada sistem x86 boleh menjadi kritikal pada penyebaran ARM64.
Proses penyahpepijatan juga menekankan kepentingan mempunyai jurutera yang boleh berfikir merentasi berbilang tahap pengekstrakan, dari kod aplikasi peringkat tinggi sehingga ke dalaman penyusun dan seni bina pemproses. Seperti yang dinyatakan oleh seorang ahli komuniti, pepijat penyusun telah menjadi semakin jarang apabila alat bertambah baik, tetapi ia masih berlaku dan memerlukan teknik penyiasatan yang canggih.
Penemuan ini berfungsi sebagai peringatan bahawa dalam sistem teragih yang beroperasi pada skala besar, walaupun peristiwa satu dalam sejuta berlaku secara berkala. Apa yang mungkin dianggap sebagai kes tepi dalam kebanyakan persekitaran menjadi isu pengeluaran apabila anda mengendalikan trafik berskala internet. Ia juga menunjukkan nilai ekosistem sumber terbuka di mana pepijat sedemikian boleh dikenal pasti, dilaporkan dan dibaiki dengan pantas melalui kerjasama antara syarikat dan penyelenggara bahasa.
Apabila perisian terus berkembang dan seni bina baru mendapat prominen, interaksi halus yang serupa antara penyusun, runtime dan perkakasan kemungkinan akan terus timbul. Pendekatan sistematik pasukan Cloudflare untuk penyahpepijatan menyediakan pelan bagaimana organisasi kejuruteraan boleh menangani masalah yang mencabar sedemikian.

