-
केवल ARM64 पर होने वाला क्रैश
- EdgeDB के नेटवर्क I/O कोड को Python से Rust में पोर्ट करने की प्रक्रिया के दौरान ARM64 CI runner पर टेस्ट बीच-बीच में फेल होने लगे।
- शुरुआत में यह deadlock जैसा लगा, लेकिन वास्तव में process क्रैश हो रही थी और test runner इसे पहचान नहीं पा रहा था।
-
शुरुआती सिद्धांत
- यह समझने के लिए कि समस्या केवल ARM64 पर ही क्यों हो रही थी, memory model के अंतर पर विचार किया गया।
- Intel का memory model अधिक सख्त है, जबकि ARM का memory model अपेक्षाकृत कमजोर है।
-
CI मशीन पर debugging
- AWS में ARM64 runner से सीधे कनेक्ट होकर समस्या की जांच की गई।
- process क्रैश होकर core dump छोड़ रही थी, और उसकी जांच से समस्या का कारण पता चला।
-
असली कारण: setenv और getenv
setenv multi-threaded environment में सुरक्षित नहीं है, और getenv के साथ उसकी interaction से क्रैश हो सकती है।
- environment variables का पुनः असाइनमेंट ही समस्या का कारण निकला।
-
openssl_probe से संबंध
openssl-probe के SSL_CERT_FILE और SSL_CERT_DIR environment variables सेट करने के दौरान समस्या हुई।
- Rust का
rust-native-tls इन environment variables को सेट करते समय क्रैश पैदा कर रहा था।
-
केवल ARM64 Linux पर ही ऐसा क्यों हुआ
- क्रैश होने के लिए कई शर्तों का एक साथ पूरा होना जरूरी था, जिनमें environment variables की संख्या और I/O failure जैसी स्थितियां शामिल थीं।
-
समाधान
reqwest के rust-native-tls/openssl backend से rustls पर स्विच करने का निर्णय लिया गया।
- Rust project environment-setting functions को unsafe बनाने की योजना बना रहा है, और
glibc project getenv की thread safety बेहतर कर रहा है।
4 टिप्पणियां
Setenv thread-safe नहीं है, और C इसे ठीक नहीं करना चाहता
Setenv फ़ंक्शन फिर से परेशानी खड़ी कर रहा है।
मैं शीर्षक इस तरह लिखूँगा: 'C stdlib की thread-unsafety को वह Rust भी नहीं बचा सकती जिसे सुरक्षित कहा जाता है' :)
मैंने इसे निश्चित रूप से समझ लिया है।
Hacker News राय
Rust के अगले edition में environment setters को unsafe बनाया जाएगा। इसका असर उन crates पर पड़ सकता है जिनमें conflict होता है
set_varऔरremove_varके लिए 2024 edition मेंunsafe {}block का इस्तेमाल करना होगाglibc के लिए एक patch ने
getenvको अधिक safe बनाया, लेकिन C अब भी environment तक direct access की अनुमति देता है, इसलिए यह पूरी तरह safe नहीं हैsetenvको multithread-safe बनाने से हिचक रहे हैं, लेकिन कम से कम एक नया thread-safe API परिभाषित किया जाना चाहिएLinux पर environment से जुड़े bugs झेलना मानो एक rite of passage जैसा माना जाता है
getenv_r()देना, उसेsetenv()के साथ synchronize करना, और compile/link समय warnings देना समस्या सुलझाने में मददगार होताenvironment variables का उपयोग करके configuration करना "12-factor app" movement का हिस्सा था, लेकिन इसे एक बेवकूफ़ी भरा तरीका माना गया है
Amazon AWS पर चलने वाली CI machines का फ़ायदा यह है कि वे असली root user उपलब्ध कराती हैं
यह non-intuitive bugs की तह तक जाने वाला एक शानदार लेख है
env::set_varअब unsafe हैset_varयाremove_varका उपयोग न करना ही एकमात्र safe विकल्प हैइससे वह अनुभव याद आता है जब
setproctitleकिसी खास codebase में काम नहीं कर रहा थाnumpyimport करने के बादsetproctitleकाम नहीं करता था, क्योंकिnumpyinitialization के दौरानgetenvयाsetenvcall होने से environ का address बदल गया था