دیباگ (حالت اشکالزدایی) — پیکربندی کمپیلاسیون برنامه موبایل است که در آن کمپایلر اطلاعات سمبلیک را وارد میکند، بهینهسازی کد را غیرفعال میکند و برای تجزیه و تحلیل گامبهگام دیباگر را متصل میکند. به گزارش Android Developers، بیلد Debug شامل سمبلهای اشکالزدایی است، منابع را فشرده نمیکند و امکان اتصال بازرسی پایگاه داده و درخواستهای شبکه را فراهم میکند. حالت Debug در مقابل بیلد Release قرار میگیرد: در Debug توسعهدهنده برای شفافیت اجرای کد، عملکرد را قربان میدهد.
نکات کلیدی
Debug (اشکالزدایی) — صرفا یک علم کمپایلر نیست، بلکه مجموعهای از تنظیمات است که برنامه را برای توسعهدهنده شفاف میکند. در حالت Debug، کمپایلر جدول اسامی سمبولیک (DWARF) را به فایل اجرایی اضافه میکند که کد ماشین را با سطور منبع مرتبط میسازد. بدون این جدول، دیباگر نمیتواند نشان دهد که کدام سطر کد در حال حاضر اجرا میشود.
دیباگر — برنامهای است که برنامه شما را در یک محیط کنترل شده اجرا میکند. میتوانید اجرا را در هر سطری (breakpoint) متوقف کنید، مقادیر تمام متغیرها را در حوزه جاری مشاهده کنید، آنها را در حال اجرا تغییر دهید و اجرا را ادامه دهید. برای پلتفرمهای موبایل، دیباگر استاندارد LLDB است — کامپوننت LLVM که هم در Xcode و هم در Android Studio استفاده میشود.
حالت Debug همچنین بررسیهای افزوده را که در Release غیرفعال هستند فعال میکند: تأکیدها (assertions)، بررسی مرزهای آرایه، آشکارسازهای نشت حافظه و ثبت گسترده. این بررسیها کار برنامه را کند میکنند، اما خطاها را در مراحل اولیه توسعه — قبل از اینکه کد به کاربر برسد — شناسایی میکنند.
تفاوت بین بیلدهای Debug و Release اساسی است: اینها دو مجموعه متفاوت از علمهای کمپایلر، تنظیمات امضا و تنظیمات بستهبندی هستند. درک این تفاوتها از وضعیتهایی که «در شبیهساز کار میکند، اما روی دستگاه واقعی نه» جلوگیری میکند.
| پارامتر | Debug | Release |
|---|---|---|
| بهینهسازی | غیرفعال (-O0) | فعال (-Os یا -O2) |
| سمبلها | جدول کامل DWARF | سمبلهای Stripped (حذف شده) |
| امضا | گواهینامه Development | گواهینامه Distribution |
| پروفایلها | Debug provisioning profile | App Store / Ad Hoc profile |
| ثبت رویداد | کامل (تمام سطوح) | غیرفعال یا حداقل |
| ابهامسازی | غیرفعال | فعال (ProGuard/R8) |
| اندازه .apk/.ipa | بزرگتر (سمبلها + بدون فشردگی) | کوچکتر (R8 + منابع) |
بیلد Debug در تمام مراحل توسعه و آزمایش روی دستگاههای محلی استفاده میشود. بیلد Release پیش از ارسال به App Store Connect یا Google Play Console ساخته میشود. اجرای اشکالزدایی روی بیلد Release از نظر فنی ممکن است، اما به دلیل تغییر نام متدها (R8) و نبود symbolication برای گزارشهای کراش، بسیار ناراحت است.
یکی از مشکلات رایج کدی است که در Debug کار میکند اما در Release دچار شکست میشود. علت آن UB (رفتار تعریفنشده) در کد است که کمپایلر در سطح بهینهسازیهای مختلف به صورت متفاوت با آن برخورد میکند. مثال تیپیک: خواندن متغیر اهلیتسازی نشده یا نقض strict aliasing. برای شناسایی چنین خطاهایی، پیش از هر بیلد Release از تحلیلگر استاتیک (Clang Static Analyzer، ktlint) استفاده کنید.
LLDB — یک دیباگر با عملکرد بالا بر پایه LLVM است که از C، C++، Objective-C، Swift و Kotlin/Native پشتیبانی میکند. LLDB رابط REPL را فراهم میکند که در آن میتوان عبارات دلخواه را اجرا کرد، مقادیر متغیرها را تغییر داد و در زمینه برنامه متوقف شده، توابع را فراخوانی کرد.
Breakpoint — ابزار کلیدی دیباگر. شما روی یک سطر کد نقطهای قرار میدهید و برنامه وقتی اجرا به آن سطر میرسد متوقف میشود. LLDB چند نوع نقطه را پشتیبانی میکند: شرطی (فقط در صورت تحقق شرط فعال میشوند)، سمبولیک (بر روی فراخوانی تابع) و یکبارمصرف (یکبار فعال شده و خودکار حذف میشوند).
Watchpoint — نقطه مشاهده تغییر متغیر. شما یک آدرس حافظه را مشخص میکنید و دیباگر در هر نوشتن به آن آدرس، اجرا را متوقف میکند. این ابزار در جستجوی مسابقه دادهها و تغییرات نادرست اشیاء مشترک ضروری است. برای مشاهده سلسلمراتب UIKit از UIView Inspector موجود در Xcode استفاده کنید.
// تنظیم breakpoint شرطی
(lldb) breakpoint set --name "viewDidLoad" --condition "self.isViewLoaded == false"
// Watchpoint بر ویژگی
(lldb) watchpoint set variable self->_loadingState
// اجرای کد در زمینه توقف
(lldb) expr self.view.backgroundColor = UIColor.redColor
هر دو IDE بازرسهای گرافیکی بر پایه LLDB تولید میکنند. Android Studio شامل Layout Inspector (مشاهده سلسلمراتب View)، Network Inspector (ردیابی درخواستهای HTTP) و Database Inspector (SQLite بلافاصله) است. Xcode Debug Memory Graph (تحلیل نشت حافظه) و View Debugger (نمایش 3D لایههای UIKit) را فراهم میکند.
از Android 11 به بعد، اشکالزدایی از طریق Wi-Fi بدون اتصال USB کار میکند: کافی است کد QR را از Android Studio اسکن کنید. iOS از Xcode 9+ به بعد از اشکالزدایی Wi-Fi پشتیبانی میکند — دستگاه یک بار از طریق USB متصل میشود، پس از آن جلسههای اشکالزدایی میتوانند از طریق شبکه انجام شوند. برای سرورهای CI، اشکالزدایی از طریق Wi-Fi به دلیل تأخیرهای غیرقابل پیشبینی و از دست رفتن بسته، مناسب نیست، بنابراین در پایپلاینهای خودکار همیشه از USB استفاده میشود. با این حال، برای توسعه محلی، اشکالزدایی Wi-Fi بسیار راحتتر است — توسعهدهنده به کابل وابسته نیست و میتواند برنامه را روی دستگاهی در آن سمت اتاق آزمایش کند.
Android Debug Bridge (ADB) — ابزاری جهت تعامل با دستگاه Android از خط فرمان است. از طریق ADB میتوان برنامه را نصب کرد، اشکالزدایی را آغاز کرد، فایلها را کپی کرد، دستورات shell را اجرا کرد و گزارشها را مشاهده کرد. Android Studio از ADB در پشت صحنه برای تمام عملیات اشکالزدایی استفاده میکند.
Android Studio از دو حالت اشکالزدایی پشتیبانی میکند: Run (عمل عادی) و Debug (عمل با دیباگر متصل). در حالت Debug میتوانید مستقیماً در ویرایشگر breakpoint قرار دهید، متغیرها را در Debug Tool Window مشاهده کنید و عبارات را در Evaluate Expression ارزیابی کنید. برای اشکالزدایی فرآیندهای پسزمینه (Service، BroadcastReceiver) از Attach Debugger to Android Process استفاده کنید.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Breakpoint در اینجا اجرا را متوقف میکند
val button = findViewById<Button>(R.id.btn_debug)
button.setOnClickListener {
startDebugProcess()
}
}
private fun startDebugProcess() {
val data = fetchDataFromApi()
Log.d("Debug", "Data loaded: $data")
}
}
دستورات ADB shell بدون دسترسی root به سیستم فایلی دستگاه دسترسی میدهند. میتوانید محتوای پوشه databases را مشاهده کرده، فایل .db را به کامپیوتر کپی کرده و آن را با هر کلینت SQLite باز کرد. Android Studio Database Inspector این فرآیند را خودکار میکند: شما دادههای زنده پایگاه را در زمان واقعی میبینید و میتوانید مستقیماً از IDE پرسجوهای SQL را اجرا کنید.
Xcode محیط اشکالزدایی یکپارچه بر پایه LLDB فراهم میکند. توسعهدهنده میتواند برنامه را روی شبیهساز یا دستگاه فیزیکی اجرا کند، breakpoint قرار دهد و از Debug Navigator برای کنترل جریانهای اجرا استفاده کند. بر خلاف Android، iOS بدون تنظیمات ویژه اجازه اجرای دو بیلد Debug به صورت همزمان روی یک دستگاه را نمیدهد.
شبیهساز برنامه را به عنوان یک فرآیند ماتیو macOS اجرا میکند که سریعترین چرخه اشکالزدایی را فراهم میکند. در دستگاه فیزیکی، اشکالزدایی از طریق USB یا Wi-Fi (از iOS 16 به بعد) انجام میشود و LLDB با debugserver روی دستگاه ارتباط برقرار میکند. عملکرد اشکالزدایی روی دستگاه به دلیل پهنای باند محدود USB 2.0 پایینتر است، اما تنها دستگاه فیزیکی امکان آزمایش سناریوهای واقعی را فراهم میکند: اعلامهای push، دوربین، حسگرها.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private func setupUI() {
let label = UILabel()
label.text = "Debug Mode"
label.textColor = .systemBlue
view.addSubview(label)
}
}
Xcode Organizer گزارشهای کراش را از دستگاههای آزمایشگران از طریق Crash Logs جمعآوری میکند. برای symbolication (تبدیل آدرسها به نامهای توابع) فایل .dSYM مورد نیاز است که در هر بیلد Debug تولید میشود. در بیلد Release نیز dSYM ایجاد میشود، اما گزارشهای کراش از App Store را باید دستی یا از طریق خدمات bitcode به Organizer بارگذاری کرد.
سوالات متداول
از نظر فنی بله — از طریق Ad Hoc با گواهینامه Debug، اما Apple و Google این کار را توصیه نمیکنند. بیلد Debug حاوی سمبلهای اشکالزدایی و عملکرد پایینتری است که UX را بدتر کرده و اندازه برنامه را 2–3 برابر افزایش میدهد.
دلیل — بهینهسازی کمپایلر غیرفعال (-O0). کمپایلر توابع را درونکابی نمیکند، کد مرده را حذف نمیکند و تمام متغیرهای وسطی را نگه میدارد. به علاوه، Debug بررسیهای تأکید و مرزهای آرایه را که در Release وجود ندارند فعال میکند.
در Xcode Window → Devices and Simulators را انتخاب کرده و گزینه «Connect via network» را برای دستگاه خود فعال کنید. دستگاه و Mac باید در یک شبکه Wi-Fi باشند. پس از یک بار اتصال از طریق USB، اشکالزدایی در عملکردهای بعدی از طریق Wi-Fi کار خواهد کرد.
Attach to process امکان اتصال دیباگر به یک فرآیند در حال اجرا را بدون راهاندازی مجدد برنامه فراهم میکند. این برای اشکالزدایی Service، BroadcastReceiver یا فرآیندهایی که توسط رویداد سیستم آغاز میشوند، مفید است جایی که Debug Run استاندارد قابل استفاده نیست.
NSLog و print به صورت پیشفرض فقط در تنظیمات Debug خروجی را نشان میدهند. برای Release از os_log با علم OSLogType.default استفاده کنید — پیامها را در Unified Logging System ذخیره میکند و از طریق Console.app روی Mac قابل دسترس است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید