-
Yalnızca ARM64'te ortaya çıkan çökme
- EdgeDB'nin ağ I/O kodunu Python'dan Rust'a taşırken, ARM64 CI runner'larında testlerin aralıklı olarak başarısız olduğu bir sorun ortaya çıktı.
- İlk başta bunun bir deadlock olduğu düşünüldü, ancak gerçekte süreç çöküyordu ve test runner bunu tespit edemiyordu.
-
İlk teori
- Sorunun neden yalnızca ARM64'te ortaya çıktığını anlamak için bellek modeli farkları dikkate alındı.
- Intel'in bellek modeli daha katıyken, ARM daha zayıf bir bellek modeline sahiptir.
-
CI makinesinde hata ayıklama
- Sorunu araştırmak için AWS üzerinde ARM64 runner'a doğrudan bağlanıldı.
- Süreç çökerek bir core dump bıraktı ve bunun incelenmesiyle sorunun nedeni belirlendi.
-
Gerçek neden: setenv ve getenv
setenv, çok iş parçacıklı ortamlarda güvenli değildir ve getenv ile etkileşiminde çökme yaratabilir.
- Sorunun nedeninin ortam değişkenlerinin yeniden atanması olduğu ortaya çıktı.
-
openssl_probe ile bağlantı
openssl-probe, SSL_CERT_FILE ve SSL_CERT_DIR ortam değişkenlerini ayarlarken sorun oluşuyordu.
- Rust'ın
rust-native-tls bileşeni bu ortam değişkenlerini ayarlarken çökme meydana geliyordu.
-
Neden yalnızca ARM64 Linux'ta ortaya çıktı
- Çökmenin gerçekleşmesi için birden fazla koşulun aynı anda sağlanması gerekiyor; ortam değişkenlerinin sayısı ve I/O hataları bu koşullar arasında yer alıyor.
-
Çözüm
reqwest'in rust-native-tls/openssl backend'inden rustls'e geçilmesine karar verildi.
- Rust projesi ortam yapılandırma işlevlerini
unsafe yapmayı planlıyor; glibc projesi ise getenv'in thread safety özelliğini iyileştiriyor.
4 yorum
Setenv thread-safe değil ve C bunu düzeltmek istemiyor
Setenv fonksiyonu yine sorun çıkarıyor.
Ben başlığı şöyle yazardım: 'C stdlib'in thread-unsafe olması, o güvenli denilen Rust'u bile kurtaramaz'. :)
Kesinlikle anladım.
Hacker News yorumu
Rust'un bir sonraki sürümünde ortam değişkeni ayarlayıcıları güvensiz hale getirilecek. Bu, çakışmaya yol açan crate'leri etkileyebilir
set_varveremove_var, 2024 sürümündeunsafe {}bloğu gerektirecekglibc için hazırlanan bir yama
getenv'i daha güvenli hale getirdi, ancak C hâlâ ortama doğrudan erişime izin verdiği için tamamen güvenli değilsetenv'i çok iş parçacıklı kullanım için güvenli hale getirme konusunda isteksiz, ancak en azından yeni bir thread-safe API tanımlanmalıLinux'ta ortamla ilgili hatalar yaşamak bir tür geçiş ritüeli gibi görülüyor
getenv_r()sağlamak, bunusetenv()ile senkronize etmek ve derleme/bağlama sırasında uyarılar vermek sorunun çözümüne yardımcı olabilirdiOrtam değişkenleriyle yapılandırma yapmak "12-factor app" hareketinin bir parçasıydı, ancak bunun aptalca bir yöntem olduğu düşünülüyor
Amazon AWS üzerinde çalışan CI makineleri gerçek root kullanıcısı sağladığı için avantajlı
Sezgisel olmayan bir hatayı derinlemesine inceleyen harika bir makale
env::set_varartık güvensizset_varveyaremove_varkullanmamak tek güvenli seçimdirsetproctitle'ın belirli bir kod tabanında çalışmadığı bir deneyimi hatırlatıyornumpyiçe aktarıldıktan sonrasetproctitleçalışmıyordu; bunun nedeninumpybaşlatılırken yapılangetenvveyasetenvçağrıları yüzünden environ adresinin değişmiş olmasıydı