ICP·Devآی‌سی‌پی‌·دِو
بازگشت به مقالات
راست۶ تیر ۱۴۰۵2 دقیقه مطالعه

طلاق وب‌اسمبلی: چرا راست بالاخره `--allow-undefined` را از بین برد

راست پرچم لینکر `--allow-undefined` را به طور دائمی از تمام هدف‌های وب‌اسمبلی حذف کرده است. این تغییر بنیادین و شکننده، خطاهای خاموش زمان اجرا را از بین می‌برد و امنیت در سطح بومی را به توسعه وب‌اسمبلی در فضای ابری، لبه و مرورگر می‌آورد.

نکات کلیدی

  • راست پرچم لینکر `--allow-undefined` را به طور دائمی از تمام هدف‌های وب‌اسمبلی حذف کرده است
  • این تغییر بنیادین و شکننده، خطاهای خاموش زمان اجرا را از بین می‌برد و امنیت در سطح بومی را به توسعه وب‌اسمبلی در فضای ابری، لبه و مرورگر می‌آورد
اشتراک‌گذاری
طلاق وب‌اسمبلی: چرا راست بالاخره `--allow-undefined` را از بین برد

طلاق وب‌اسمبلی: چرا راست بالاخره --allow-undefined را از بین برد

وب‌اسمبلی (Wasm) مدت‌هاست که وعده آینده‌ای امن (ایزوله‌شده در ساندباکس) و با کارایی بالا را برای کدهایی داده است که در هر کجا، از تب‌های مرورگر گرفته تا ابرهای لبه‌ای (edge) مانند Cloudflare Workers اجرا می‌شوند. اما سال‌هاست که فرآیند کامپایل وب‌اسمبلی در راست راز کثیفی را با خود یدک می‌کشید؛ یک راهکار موقت تاریخی که به آرامی امنیت زمان کامپایل معروف راست را دور می‌زد.

با انتشار نسخه پایدار Rust 1.96.0، تیم کامپایلر راست رسماً پیوند خود را با این میراث قدیمی قطع کرد و پرچم لینکر --allow-undefined را به طور دائمی از تمامی هدف‌های (targets) وب‌اسمبلی حذف نمود. این یک تغییر بنیادین و شکننده (breaking change) بزرگ است که نقطه عطف مهمی در بلوغ معماری وب‌اسمبلی به شمار می‌رود.

میراث ایمپورت‌های خاموش

برای درک اهمیت این تغییر، باید به نحوه کامپایل وب‌اسمبلی نگاهی بیندازیم. برخلاف سیستم‌های بومی (مانند لینوکس یا ویندوز) که اگر به تابعی غیرموجود ارجاع دهید کامپایل آن‌ها با خطا مواجه می‌شود، هدف‌های اولیه واسم (Wasm) در راست راه میانبری را در پیش گرفته بودند. آن‌ها به طور خودکار آرگومان --allow-undefined را به لینکر زیربنایی یعنی wasm-ld پاس می‌دادند.

اگر یک تابع میزبان خارجی را در کد راست خود به این صورت تعریف می‌کردید:

rust
unsafe extern "C" {
    fn my_host_function();
}

و فراموش می‌کردید کتابخانه‌ای که آن را تعریف می‌کند لینک کنید، کامپایلر هیچ اعتراضی نمی‌کرد. در عوض، به طور خاموش یک باینری وب‌اسمبلی تولید می‌کرد که ایمپورت از یک ماژول عمومی "env" را اعلام می‌کرد:

wat
(module 
  (import "env" "my_host_function" (func $my_host_function))
)

کامپایلر حل مسئله نمادها (symbol resolution) را به تعویق می‌انداخت و آن را به عهده محیط میزبان می‌گذاشت تا در زمان اجرا حل کند.

خطر به تعویق انداختن مشکل

اگرچه این کار برای راه‌اندازی اولیه اکوسیستم راحت بود، اما باگ‌های جدی به همراه داشت. برجسته‌ترین آن‌ها خرابی‌های خاموش در زمان اجرا بود. اگر یک غلط املایی ساده مرتکب می‌شدید — مثلاً نوشتن mylibraryinit به جای mylibrary_init — کد با موفقیت کامپایل می‌شد. اما به محض اجرای کد در محیط عملیاتی (production)، برنامه با یک خطای مبهم "missing import" کرش می‌کرد.

علاوه بر این، ابزارهای پایین‌دستی مانند wasm-bindgen یا wasm-tools اغلب با این ایمپورت‌های حل‌نشده و غیرمنتظره به مشکل می‌خوردند و خطاهای بسیار گیج‌کننده‌ای ایجاد می‌کردند که ردیابی آن‌ها تا سورس اصلی راست فوق‌العاده دشوار بود.

یک گرافیک برداری انتزاعی بسیار دقیق که نشان می‌دهد...

ایمن‌سازی خط لوله توسعه

اکنون راست با ایجاد خطاهای سخت‌گیرانه لینکر برای نمادهای تعریف‌نشده، با وب‌اسمبلی دقیقاً مانند هر هدف بومی درجه‌یک (tier-1) دیگری رفتار می‌کند.

اگر پایگاه کد شما عمداً از ایمپورت‌های ارائه‌شده توسط میزبان استفاده می‌کند، اکنون باید با استفاده از اتریبیوت #[link]، ماژول هدف را صراحتاً اعلام کنید:

rust
#[link(wasm_import_module = "my_custom_host")]
extern "C" {
    fn my_host_function();
}

اگر در حال نگهداری از یک پایگاه کد قدیمی و بسیار بزرگ هستید و برای بازگرداندن رفتار قبلی به یک راه فرار فوری نیاز دارید، می‌توانید به صورت دستی به کامپایلر دستور دهید تا این پرچم را از طریق پیکربندی cargo یا ترمینال دوباره ارسال کند:

bash
RUSTFLAGS="-C link-arg=--allow-undefined" cargo build --target wasm32-unknown-unknown

مسیر رسیدن به واسم آماده برای محیط عملیاتی

حذف --allow-undefined گام ضروری برای بلوغ است. از آنجا که وب‌اسمبلی جایگاه خود را در معماری‌های لبه سازمانی، محیط‌های اجرای بدون سرور (serverless) و ساندباکس‌های امن تثبیت می‌کند، کامپایل با توجیه "روی سیستم من کار می‌کند" دیگر قابل قبول نیست. راست با اعمال بررسی‌های سخت‌گیرانه در زمان کامپایل، کل اکوسیستم واسم را خطا به خطا در لینکر، به مراتب امن‌تر کرده است.

برچسب‌ها

#راست#وب‌اسمبلی#کامپایلر#کارگو#واسم

منابع و ارجاعات مستند

پیشنهاد مطالعه بعدی

خوشتان آمد؟ مقاله بعدی را بگیرید

در خبرنامه عضو شوید تا راهنمای بعدی در ایمیلتان باشد — بدون مزاحمت، لغو عضویت در هر زمان.