Debug (وضع تصحيح الأخطاء) — هو تكوين بناء للتطبيقات المحمولة حيث يضم المترجم معلومات رمزية، ويعطل تحسين الكود ويوصل المصحح لتحليل التنفيذ خطوة بخطوة. وفقاً لـ Android Developers، يحتوي بناء Debug على رموز تصحيح الأخطاء، ولا يضغط الموارد ويسمح بتوصيل مفحص قواعد البيانات وطلبات الشبكة. وضع Debug يقابل بناء Release: في Debug يضحي المطور بالأداء من أجل شفافية تنفيذ الكود.
النقاط الرئيسية
Debug ليس مجرد علامة مترجم، بل مجموعة كاملة من الإعدادات التي تجعل التطبيق شفافاً للمطور. في وضع Debug، يضيف المترجم جدول أسماء رمزية (DWARF) إلى الملف التنفيذي، الذي يربط الكود الآلي بأسطر المصدر. بدون هذا الجدول، لا يمكن للمصحح إظهار أي سطر من الكود يتم تنفيذه حالياً.
المصحح (debugger) هو برنامج يشغل تطبيقك في بيئة محكومة. يمكنك إيقاف التنفيذ عند أي سطر (breakpoint)، وعرض قيم جميع المتغيرات في النطاق الحالي، وتغييرها أثناء التشغيل ومتابعة التنفيذ. للمنصات المحمولة، المصحح القياسي هو LLDB — مكون من LLVM يُستخدم في كل من Xcode وAndroid Studio.
يتضمن وضع Debug أيضاً فحوصات إضافية معطلة في Release: التأكيدات، فحوصات حدود المصفوفات، كواشف تسرب الذاكرة وتسجيل موسع. هذه الفحوصات تبطئ التطبيق لكنها تكتشف الأخطاء في المراحل المبكرة من التطوير — قبل أن يصل الكود إلى المستخدم.
الفرق بين بنيات Debug وRelease جوهري: إنها مجموعتان مختلفتان من علامات المترجم، تكوينات التوقيع وإعدادات التغليف. فهم هذه الفروق يساعد في تجنب المواقف التي يكون فيها «يعمل في المحاكي لكن ليس على الجهاز الحقيقي».
| المعامل | Debug | Release |
|---|---|---|
| التحسين | معطل (-O0) | مفعل (-Os أو -O2) |
| الرموز | جدول DWARF كامل | محذوفة |
| التوقيع | شهادة تطوير | شهادة توزيع |
| الملفات التعريفية | ملف تعريف تزويد Debug | ملف App Store / Ad Hoc |
| التسجيل | كامل (جميع المستويات) | معطل أو أدنى |
| التمويه | معطل | مفعل (ProGuard/R8) |
| حجم .apk/.ipa | أكبر (رموز + بدون ضغط) | أصغر (R8 + موارد) |
بناء Debug يُستخدم في جميع مراحل التطوير والاختبار على الأجهزة المحلية. بناء Release يُجمَّع قبل الإرسال إلى App Store Connect أو Google Play Console. تصحيح الأخطاء على بناء Release ممكن تقنياً لكنه غير مريح للغاية بسبب إعادة تسمية الدوال (R8) وغياب symbolication لسجلات الأعطال.
مشكلة شائعة هي كود يعمل في Debug لكنه يتعطل في Release. السبب هو UB (سلوك غير محدد) في الكود الذي يعالجه المترجم بشكل مختلف مع مستويات تحسين مختلفة. مثال نموذجي: قراءة متغير غير مهيأ أو انتهاك strict aliasing. لاكتشاف هذه الأخطاء، استخدم محللاً ثابتاً (Clang Static Analyzer، ktlint) قبل كل بناء Release.
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
توفر كلتا البيئتين مفحصات رسومية فوق LLDB. يتضمن Android Studio Layout Inspector (تسلسل العرض)، Network Inspector (تتبع طلبات HTTP) وDatabase Inspector (SQLite في الوقت الفعلي). يوفر Xcode Debug Memory Graph (تحليل تسرب الذاكرة) وView Debugger (عرض ثلاثي الأبعاد لطبقات UIKit).
ابتداءً من Android 11، يعمل التصحيح عبر Wi-Fi بدون اتصال USB: فقط امسح رمز QR من Android Studio. يدعم iOS التصحيح عبر Wi-Fi منذ Xcode 9+ — يتصل الجهاز مرة واحدة عبر USB، وبعدها يمكن لجلسات التصحيح أن تعمل عبر الشبكة. التصحيح عبر Wi-Fi غير مناسب لخوادم CI بسبب زمن الوصول غير المتوقع وفقدان الحزم، لذلك تستخدم خطوط الأنابيب الآلية USB دائماً. مع ذلك، للتطوير المحلي، التصحيح عبر Wi-Fi أكثر راحة بشكل ملحوظ — المطور غير مقيد بكابل ويمكنه اختبار التطبيق على جهاز في الطرف الآخر من الغرفة.
Android Debug Bridge (ADB) هو أداة عالمية للتفاعل مع جهاز Android من سطر الأوامر. عبر ADB يمكنك تثبيت تطبيق، بدء التصحيح، نسخ الملفات، تنفيذ أوامر shell وعرض السجلات. يستخدم Android Studio ADB داخلياً لجميع عمليات التصحيح.
Android Studio يدعم وضعي تصحيح: Run (تشغيل عادي) وDebug (تشغيل مع مصحح متصل). في وضع Debug يمكنك تعيين breakpoints مباشرة في المحرر، وعرض المتغيرات في نافذة Debug Tool وتقييم التعبيرات في 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")
}
}
أوامر shell ADB توفر وصولاً إلى نظام ملفات الجهاز بدون صلاحيات الجذر. يمكنك عرض محتويات مجلد databases، نسخ ملف .db إلى جهاز الكمبيوتر وفتحه بأي عميل SQLite. يقوم Android Studio Database Inspector بأتمتة هذه العملية: ترى بيانات قاعدة البيانات الحية في الوقت الفعلي ويمكنك تنفيذ استعلامات SQL مباشرة من IDE.
Xcode يوفر بيئة تصحيح متكاملة مبنية على LLDB. يمكن للمطور تشغيل التطبيق على محاكي أو جهاز فعلي، وتعيين breakpoints واستخدام Debug Navigator للتحكم في سلاسل التنفيذ. على عكس Android، لا يسمح iOS بتشغيل بنيتي Debug في وقت واحد على نفس الجهاز بدون تكوين خاص.
المحاكي يشغل التطبيق كعملية macOS أصلية، مما يوفر أسرع دورة تصحيح. على الجهاز الفعلي، يتم التصحيح عبر USB أو Wi-Fi (ابتداءً من iOS 16)، ويتواصل LLDB مع debugserver على الجهاز. أداء التصحيح على الجهاز أقل بسبب عرض النطاق المحدود لـ USB 2.0، لكن فقط الجهاز الفعلي يسمح باختبار السيناريوهات الحقيقية: الإشعارات الفورية، الكاميرا، أجهزة الاستشعار.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private func setupUI() {
let label = UILabel()
label.text = "وضع Debug"
label.textColor = .systemBlue
view.addSubview(label)
}
}
Xcode Organizer يجمع سجلات الأعطال من أجهزة المختبرين عبر Crash Logs. للـ symbolication (تحويل العناوين إلى أسماء دوال) يلزم ملف .dSYM الذي يتم إنشاؤه مع كل بناء Debug. في بناء Release، يتم إنشاء dSYM أيضاً، لكن سجلات الأعطال من App Store يجب تحميلها إلى Organizer يدوياً أو عبر خدمة bitcode.
الأسئلة المتكررة
تقنياً نعم — عبر توزيع Ad Hoc بشهادة Debug، لكن Apple وGoogle لا توصيان بذلك. يحتوي بناء Debug على رموز تصحيح وأداء منخفض، مما يضعف تجربة المستخدم ويزيد حجم التطبيق 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 تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا