LLDB (Low-Level Debugger) هو مصحح من الجيل الجديد من مشروع LLVM، مضمن في Xcode لتصحيح أخطاء التطبيقات على iOS وmacOS وtvOS وwatchOS. على عكس GDB، يستخدم LLDB بنية معيارية مع مترجم LLVM، مما يوفر سرعة ودقة عالية. وفقًا لـ مشروع LLVM، يدعم LLDB تصحيح الأخطاء بلغات C وObjective-C وC++ وSwift مع مجموعة كاملة من الوظائف: نقاط التوقف (breakpoints)، نقاط المراقبة (watchpoints)، فحص الذاكرة والتنفيذ خطوة بخطوة.
النقاط الرئيسية
LLDB هو مصحح مفتوح المصدر مبني على مكتبات مشروع LLVM. حل محل GDB في Xcode 5 ومنذ ذلك الحين أصبح أداة التصحيح الرئيسية لنظام Apple البيئي بأكمله. على عكس GDB المتجانس، يتم تنفيذ LLDB كمجموعة من المكتبات المتفاعلة: كل وظيفة — من تحليل التعبيرات إلى إدارة الذاكرة — موجودة في وحدة منفصلة، مما يبسط الصيانة والتوسعة.
تشمل القدرات الرئيسية لـ LLDB: تعيين نقاط التوقف من أي نوع، نقاط المراقبة لتتبع تغييرات المتغيرات، فحص الذاكرة والسجلات، التنفيذ خطوة بخطوة، تقييم التعبيرات التعسفية في سياق برنامج متوقف، وتشغيل نصوص Python البرمجية للأتمتة. وفقًا لمستودع LLVM، يدعم LLDB أكثر من 200 أمر تصحيح وهو متوافق مع تنسيقي DWARF وMach-O — التنسيقان الرئيسيان لمعلومات التصحيح في نظام Apple البيئي.
ميزة مهمة لـ LLDB هي التكامل العميق مع Clang. باستخدام نفس المترجم لتحليل وتجميع الكود المصدري، يمكن لـ LLDB تقييم تعبيرات C++ وObjective-C بدقة غير متاحة في GDB. لتصحيح أخطاء Swift، يستخدم LLDB وحدة Swift Language Runtime منفصلة تفهم دلالات اللغة: الأنواع الاختيارية، البروتوكولات، الأدوية العامة، وإدارة الذاكرة عبر ARC.
ظهر الإصدار الأول من LLDB في عام 2010 كجزء من LLVM 2.8. بحلول عام 2013، حل محل GDB بالكامل في Xcode. في عام 2019، مع إصدار Xcode 11، حصل LLDB على دعم لنقاط توقف أخطاء Swift ومحلل تعبيرات محسّن لـ Swift. وفقًا لـ Apple، منذ iOS 14، تعمل حزمة التصحيح بالكامل للمحاكي أيضًا عبر LLDB، مما يؤكد مكانته كأداة التصحيح الرئيسية للمنصة.
بنية LLDB مبنية على مبدأ الخدمات المصغرة: كل نظام فرعي موجود كمكتبة منفصلة (dylib)، متصلة بالآخرين عبر API مشترك. وهذا يميزه عن GDB، حيث يتم دمج جميع الوظائف في ملف ثنائي واحد. يسمح الهيكل المعياري باستخدام مكونات LLDB بشكل مستقل — على سبيل المثال، يمكن دمج محلل التعبيرات في IDE دون توصيل المصحح الكامل.
| مكون LLDB | الغرض | المكتبة |
|---|---|---|
| Core | إدارة عملية التصحيح، الأحداث، حالات الخيوط | liblldbCore.dylib |
| Expression Parser | تحليل وتنفيذ التعبيرات (C/C++/ObjC/Swift) | liblldbExpression.dylib |
| Symbol File | قراءة DWARF وMach-O وdSYM — العمل مع معلومات التصحيح | liblldbSymbol.dylib |
| Target Control | التحكم في التنفيذ: تشغيل، إيقاف، خطوات | liblldbTarget.dylib |
| Interpreter | سطر الأوامر ووضع REPL | liblldbInterpreter.dylib |
dSYM هي ملفات معلومات التصحيح التي ينشئها Xcode أثناء البناء. يستخدمها LLDB لربط الكود الآلي بالكود المصدري: بدون dSYM، يعرض المصحح عناوين الذاكرة فقط بدلاً من أسماء الوظائف وأسطر الكود. بالنسبة لتطبيقات App Store، يتم تحميل ملفات dSYM بشكل منفصل على خادم Apple وتستخدم لترميز سجلات الأعطال المستلمة من المستخدمين عبر CrashReporter.
(lldb) target create MyApp.app
(lldb) image list MyApp
MyApp - "/path/to/MyApp.app/MyApp" (arm64)
(lldb) image lookup -n fetchUserData
Address: MyApp[0x1000a3b40] (MyApp.__TEXT.__text + 12352)
Summary: `ViewController.fetchUserData()` at ViewController.swift:42
تنقسم أوامر LLDB إلى عدة فئات: التحكم في التنفيذ، إدارة نقاط التوقف، فحص البيانات، والتعامل مع الذاكرة. على عكس واجهة Xcode الرسومية، تمنح وحدة تحكم LLDB تحكمًا كاملاً في التصحيح وتسمح بعمليات غير متاحة عبر الواجهة الرسومية — على سبيل المثال، تغيير قيمة متغير أثناء التنفيذ أو تحرير نقاط التوقف بشكل مجمع.
Continue, Step Over, Step Into, Step Out — أساس دورة التصحيح. continue يستأنف التنفيذ حتى نقطة التوقف التالية. step over ينفذ السطر الحالي بالكامل. step into يدخل داخل الطريقة المستدعاة. step out يكمل الوظيفة الحالية ويعيد التحكم إلى الكود المستدعي. بالإضافة إلى ذلك، يوجد step with type filter — خطوة حتى نوع البيانات المحدد.
(lldb) thread backtrace # عرض مكدس الاستدعاءات
* thread #1, queue = 'com.apple.main-thread'
frame #0: 0x1000a3b40 ViewController`fetchUserData()
frame #1: 0x1000a2000 ViewController`viewDidLoad()
frame #2: 0x1a2b345 UIKit`UIViewController.loadView()
(lldb) frame variable # عرض المتغيرات المحلية
(Int) userId = 42
(String) endpoint = "https://api.example.com/user/42"
(lldb) thread step-over # Step Over
(lldb) thread step-in # Step Into
يوفر LLDB أوامر لعرض البيانات بأي تنسيق: memory read وframe variable وtarget variable. الصياغة الخاصة po (print object) تستدعي debugDescription لكائنات Objective-C وdescription لأنواع Swift. يتم تعيين المنسقات المخصصة عبر type summary add — مفيد لتصحيح الهياكل المعقدة مثل CGRect أو IndexPath.
(lldb) po userProfile # طباعة وصف الكائن
<UserProfile: 0x600000c4b80>
- name: "John"
- age: 30
- email: "john@example.com"
(lldb) expression userProfile.age = 31 # تغيير القيمة
(Int) $R0 = 31
(lldb) memory read 0x600000c4b80 0x600000c4bc0
0x600000c4b80: 6a 6f 68 6e 00 00 00 00 1e 00 00 00 00 00 00 00
تقييم التعبيرات في LLDB هي واحدة من أقوى الميزات، الغائبة في GDB في وقت هيمنته. يمكن لـ LLDB تنفيذ كود عشوائي بلغات C وObjective-C وC++ وSwift في سياق برنامج متوقف، بما في ذلك استدعاء الطرق وإنشاء الكائنات وتعديل الحالة. وهذا يسمح باختبار الفرضيات دون إعادة تشغيل التطبيق وإعادة الترجمة.
أمر expression يترجم وينفذ تعبيرًا في وقت تشغيل العملية قيد التصحيح. العلم -O (object description) يستدعي po. للتعبيرات متعددة الأسطر، استخدم expression -l Swift --. LLDB يترجم الكود أثناء التنفيذ عبر Clang أو Swift Compiler، يدمج النتيجة في السياق الحالي ويعيد القيمة. وفقًا لـ Apple، يتم ترجمة التعبير في 10–50 مللي ثانية حسب التعقيد.
(lldb) expr -l Swift -- UIAlertController(title: "Test", message: nil,
preferredStyle: .alert)
(lldb) expr let $arr = [1, 2, 3].map { $0 * 2 }
(lldb) po $arr
▿ 3 elements
- 0 : 2
- 1 : 4
- 2 : 6
يسمح LLDB ليس فقط بقراءة ولكن أيضًا بتعديل حالة الكائنات والمتغيرات أثناء التصحيح. هذا أمر بالغ الأهمية لاختبار الحالات الحدودية: يمكن تعيين متغير إلى nil، أو تغيير لون عنصر واجهة المستخدم، أو استبدال استجابة الخادم مباشرة في المصحح، دون إعادة الترجمة وإعادة التشغيل. تُستخدم هذه التقنية على نطاق واسع في تطوير الألعاب والتطبيقات ذات التدفقات الطويلة، حيث تستغرق إعادة التشغيل وقتًا طويلاً.
(lldb) expr self.label.text = @"Updated"
(lldb) expr -l Swift -- (self as! UIViewController).view.backgroundColor = .red
(lldb) expr let $snapshot = self.view.debugQuickLookObject()
تتيح واجهة Python API في LLDB كتابة نصوص برمجية لأتمتة التصحيح. من خلال Python، يمكن إنشاء أوامر مخصصة، ومعالجة أحداث نقاط التوقف، وإنشاء تقارير، وحتى تجاوز سلوك المصحح. يعمل مترجم Python 3 المدمج مباشرة داخل LLDB، مع إمكانية الوصول إلى كامل واجهة التصحيح عبر وحدة lldb.
يمكن تسجيل أمر LLDB جديد عبر المُزخرف @classmethod في نص Python البرمجي. بعد استيراد النص، يصبح الأمر متاحًا كأمر مدمج. على سبيل المثال، يمكن لأمر printvars عرض جميع متغيرات الإطار الحالي مع أنواعها وقيمها، منسقة لمشروع معين. تقلل الأتمتة وقت عمليات التصحيح النموذجية بنسبة 60–80%، وفقًا لاستطلاع رأي مطوري iOS على Stack Overflow.
import lldb
class PrintVarsCommand:
@classmethod
def register_class(cls, debugger, _):
handler = PrintVarsCommand()
debugger.HandleCommand('command script add -c \
print_vars.PrintVarsCommand printvars')
def __call__(self, debugger, command, exe_ctx, result):
frame = exe_ctx.frame
for var in frame.variables:
result.AppendMessage(f"{var.name}: {var.type} = {var.value}")
من خلال واجهة Python API، يمكن ربط نص برمجي بتنشيط نقطة التوقف. قم بتعيين نقطة توقف، ثم نفذ breakpoint command add وحدد دالة Python. يسمح هذا بتسجيل الحالة تلقائيًا، وإرسال البيانات إلى التحليلات، أو التحقق من الثوابت دون تدخل يدوي. وفقًا لـ LLVM، يُستخدم هذا الأسلوب في بنية Apple التحتية لجمع مقاييس الأداء أثناء التطوير.
(lldb) breakpoint set -f Model.swift -l 100
(lldb) breakpoint command add 1 -s python -o "frame = exe_ctx.frame;
print([var.name for var in frame.variables])"
REPL (Read-Eval-Print Loop) هو وضع تفاعلي لـ LLDB، يتم استدعاؤه بأمر lldb --repl أو عبر وحدة تحكم التصحيح في Xcode. في REPL، يمكن تنفيذ كود Swift أو C كما في playground، مع ردود فعل فورية. LLDB يترجم كل سطر، ينفذه ويعرض النتيجة — هذا مناسب للتجربة مع APIs، ونمذجة الخوارزميات، وتعلم ميزات اللغة الجديدة دون إنشاء مشروع.
(lldb) --repl
1> let numbers = [1, 2, 3, 4, 5]
2> numbers.filter { $0 % 2 == 0 }
$R0: [Int] = 2 values {
[0] = 2
[1] = 4
}
3> let result = numbers.reduce(0, +)
$R1: Int = 15
يدعم وضع REPL أيضًا تحميل الوحدات والأطر عبر import. على سبيل المثال، import UIKit في REPL يحمل مكتبة UIKit بأكملها، ويمكن إنشاء عناصر واجهة المستخدم، والتحقق من القيود، واختبار الرسوم المتحركة. هذه قدرة فريدة لمطوري iOS، غير متاحة في GDB — التصحيح والنمذجة في بيئة واحدة.
بفضل التكامل مع مترجم Swift، يُستخدم LLDB REPL في دورات Apple لتعليم Swift. يمكن للطلاب تنفيذ الكود سطرًا بسطر، ورؤية الأنواع والنتائج دون الانشغال بإعداد المشروع. يتبع هذا الأسلوب منهجية التعلم النشط، حيث تعمل التغذية الراجعة التفاعلية على تسريع استيعاب المواد بنسبة 40% وفقًا للأبحاث في مجال تعليم علوم الكمبيوتر.
الأسئلة المتداولة
LLDB مبني على بنية LLVM المعيارية، مما يمنحه ميزة في سرعة تقييم التعبيرات ودعم اللغات الحديثة (Swift). GDB هو مصحح متجانس لا يدعم Swift وله قدرات محدودة في البرمجة النصية.
قم بتثبيت Command Line Tools عبر xcode-select --install، ثم نفذ lldb --repl في الطرفية. LLDB متاح في /Library/Developer/CommandLineTools/usr/bin/.
نعم، عبر lldb --attach-pid PID أو process attach --name AppName. LLDB سيوقف العملية مؤقتًا، وبعد ذلك تصبح جميع أوامر التصحيح القياسية متاحة دون إعادة تشغيل التطبيق.
ملفات معلومات التصحيح dSYM مفقودة. تحقق من إعدادات Build Settings: يجب أن يكون Generate Debug Symbols بقيمة YES، وDebug Information Format بقيمة DWARF with dSYM File.
LLDB يحفظ التاريخ تلقائيًا في ~/.lldb/lldb-history. للتصدير، استخدم session save filename.txt — الأمر يحفظ جميع الأوامر المنفذة للجلسة الحالية في ملف نصي.
ملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا