5 पॉइंट द्वारा GN⁺ 2025-01-24 | 4 टिप्पणियां | WhatsApp पर शेयर करें
  • केवल 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 टिप्पणियां

 
carnoxen 2025-01-24

Setenv thread-safe नहीं है, और C इसे ठीक नहीं करना चाहता

Setenv फ़ंक्शन फिर से परेशानी खड़ी कर रहा है।

 
y15un 2025-01-24

मैं शीर्षक इस तरह लिखूँगा: 'C stdlib की thread-unsafety को वह Rust भी नहीं बचा सकती जिसे सुरक्षित कहा जाता है' :)

 
halfenif 2025-01-24

मैंने इसे निश्चित रूप से समझ लिया है।

 
GN⁺ 2025-01-24
Hacker News राय
  • Rust के अगले edition में environment setters को unsafe बनाया जाएगा। इसका असर उन crates पर पड़ सकता है जिनमें conflict होता है

    • Rust standard library में set_var और remove_var के लिए 2024 edition में unsafe {} block का इस्तेमाल करना होगा
    • मौजूदा documentation में safety issue का ज़िक्र है, लेकिन मूल रूप से इन functions को safe बनाना एक गलती थी
  • glibc के लिए एक patch ने getenv को अधिक safe बनाया, लेकिन C अब भी environment तक direct access की अनुमति देता है, इसलिए यह पूरी तरह safe नहीं है

    • C standard library maintainers setenv को multithread-safe बनाने से हिचक रहे हैं, लेकिन कम से कम एक नया thread-safe API परिभाषित किया जाना चाहिए
    • Musl के maintainer को पूरा यक़ीन नहीं है कि इस समस्या को हल नहीं किया जा सकता
  • Linux पर environment से जुड़े bugs झेलना मानो एक rite of passage जैसा माना जाता है

    • Linus और kernel POSIX bugs को ठीक करने में व्यावहारिक हैं, लेकिन glibc अब भी पीछे है
    • getenv_r() देना, उसे setenv() के साथ synchronize करना, और compile/link समय warnings देना समस्या सुलझाने में मददगार होता
  • environment variables का उपयोग करके configuration करना "12-factor app" movement का हिस्सा था, लेकिन इसे एक बेवकूफ़ी भरा तरीका माना गया है

    • environment variables की जगह YAML जैसी configuration files इस्तेमाल करना बेहतर तरीका माना गया है
  • Amazon AWS पर चलने वाली CI machines का फ़ायदा यह है कि वे असली root user उपलब्ध कराती हैं

    • लगता है कि cloud और containers के बिना local में code build और debug करने की क्षमता हमने खो दी है
  • यह non-intuitive bugs की तह तक जाने वाला एक शानदार लेख है

    • ऐसी detailed troubleshooting reports खुद करके देखने के सबसे क़रीबी अनुभव देती हैं
  • env::set_var अब unsafe है

    • single-thread programs में इसे safe तरीके से call किया जा सकता है
    • Windows पर यह single-thread और multithread दोनों तरह के programs में हमेशा safe है
    • दूसरे operating systems पर multithread programs में set_var या remove_var का उपयोग न करना ही एकमात्र safe विकल्प है
  • इससे वह अनुभव याद आता है जब setproctitle किसी खास codebase में काम नहीं कर रहा था

    • numpy import करने के बाद setproctitle काम नहीं करता था, क्योंकि numpy initialization के दौरान getenv या setenv call होने से environ का address बदल गया था