یک crash در iOS؛ از گزارش مبهم SIGBUS تا آزمایش‌های کنترل‌شده

چرا مهم است

اگر فقط گاهی رخ بدهد، کاهش تعداد خطاها ممکن است گمراهت کند. این روایت نشان می‌دهد چرا در باید بازگشت همان خطای مشخص را بسنجی، نه اینکه فقط به کاهش آمار کلی تکیه کنی.

قبل از خواندن، این‌ها را بدان۳ مفهوم
crash

توقف ناگهانی اجرای app بر اثر خطایی که ادامه اجرای عادی را ناممکن می‌کند.

در حال نگارش: crash

debugging

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

در حال نگارش: debugging

main thread

thread اصلی برنامه که در app‌های iOS اجرای بسیاری از عملیات مرتبط با UI باید روی آن انجام شود.

در حال نگارش: main thread

Abhishek Gang Deb در این مقاله، روند بررسی یک crash در یک app مصرفی بزرگ iOS را روایت می‌کند؛ خطایی که فقط در بعضی اجراها رخ می‌داد و تلاش‌های محلی توسعه‌دهندگان و تیم QA برای بازتولید آن نتیجه نمی‌داد. گزارش شامل SIGBUS و بخش‌هایی از Foundation مرتبط با پردازش attributed string بود، اما خط مشخصی از Swift را نشان نمی‌داد. SIGBUS نشانه دسترسی نامعتبر به حافظه است، نه تشخیص قطعی علت.

بررسی اولیه شامل استفاده از Zombie Objects،؜ افزودن breakpoint و بازبینی ownership و مسیرهای اجرای غیرهمگام بود. تغییراتی در مدیریت lifecycle و synchronization نیز انجام شد. نخستین hotfix نرخ کلی crash را کاهش داد، اما همان خطای هدف همچنان در نسخه منتشرشده دیده می‌شد. نکته مهم این بود که تغییر زمان‌بندی اجرا می‌تواند دفعات وقوع یک خطای حساس به زمان را کم کند، بی‌آنکه علت اصلی برطرف شده باشد.

نقطه عطف زمانی رسید که یکی از اعضای QA توانست روی دستگاه خودش، با تکرار مسیر کاربر و گاهی پس از چهار یا پنج تلاش، خطا را بازتولید کند. از آن پس، debugging به چرخه‌ای قابل‌آزمایش تبدیل شد: تغییر یک بخش، ساخت نسخه آزمایشی، نصب روی همان دستگاه و ثبت بازگشت یا عدم بازگشت crash.

نویسنده سپس به‌جای اصلاح بخش‌هایی که مشکوک به نظر می‌رسیدند، هر بار یک view یا رفتار را حذف کرد. پس از چند مرحله، محدوده بررسی به یک فایل و سپس به عملیات تبدیل HTML به attributed string با NSMutableAttributedString رسید؛ فراخوانی‌ای که در ظاهر نشانی از دسترسی ناامن به حافظه نداشت.

مقاله تأکید می‌کند که واردکردن HTML با NSAttributedString الزام اجرای روی main thread دارد؛ الزامی که در آماده‌سازی غیرهمگام صفحه به‌راحتی نادیده می‌ماند. همچنین استفاده از یک لایه مشترک مبتنی بر MainActor را محافظی قوی‌تر از تکیه بر یادآوری این قاعده در تک‌تک محل‌های فراخوانی می‌داند.

نکته کلیدی

برای بررسی ،؜ هر بار یک بخش را تغییر بده و همان مسیر را روی دستگاهی که خطا را نشان می‌دهد تکرار کن. اگر HTML را با NSAttributedString تبدیل می‌کنی، الزام اجرای آن روی را فراموش نکن.

خواندن مقاله اصلی (در زبانه‌ی جدید باز می‌شود)
برچسب‌ها (۵)