LLDB: این چه دیباگری است، دستورات اصلی و کاربرد در توسعه iOS

نویسنده: IT Sectr منتشر شده: 2026-05-07 زمان مطالعه: 9 دقیقه

LLDB (Low-Level Debugger) — دیباگر نسل جدید از پروژه LLVM که بخشی از Xcode برای دیباگ اپلیکیشن‌های iOS، macOS، tvOS و watchOS است. برخلاف GDB، LLDB از معماری ماژوالر با کامپایلر LLVM استفاده می‌کند که سرعت و دقت بالایی را فراهم می‌کند. طبق داده‌های LLVM Project، LLDB از دیباگ در زبان‌های C، Objective-C، C++ و Swift با مجموعه کامل توابع پشتیبانی می‌کند: breakpoints، watchpoints، بازرسی حافظه و اجرای گام‌به‌گام.

نکات اصلی

  • LLDB — دیباگر استاندارد Xcode با کد منبع باز مبتنی بر ابزارهای LLVM.
  • معماری ماژوالر LLDB از کتابخانه‌های جداگانه برای پارس، اجرا و تجسم تشکیل شده است که مستقل از یکدیگر هستند.
  • دستورات LLDB امکان تنظیم breakpoints، بازرسی متغیرها، اجرای عبارات و تغییر وضعیت در حین دیباگ را فراهم می‌کنند.
  • Python API LLDB امکان ایجاد اسکریپت‌های سفارشی برای خودکارسازی سناریوهای دیباگ را می‌دهد.
  • حالت REPL LLDB به عنوان یک محیط تعاملی برای آزمایش با کد در Swift و C کار می‌کند.

LLDB چیست و چگونه ساخته شده است

LLDB — یک دیباگر با کد منبع باز است که بر روی کتابخانه‌های پروژه LLVM ساخته شده است. این دیباگر در Xcode 5 جایگزین GDB شد و از آن زمان به عنوان ابزار اصلی دیباگ برای کل اکوسیستم Apple محسوب می‌شود. برخلاف GDB یکپارچه، LLDB به عنوان مجموعه‌ای از کتابخانه‌های همکار پیاده‌سازی شده است: هر تابع — از پارس عبارات تا کار با حافظه — در یک ماژول جداگانه قرار گرفته است که نگهداری و گسترش را آسان‌تر می‌کند.

قابلیت‌های اصلی LLDB عبارتند از: تنظیم breakpoints از هر نوع، watchpoints برای ردیابی تغییرات متغیرها، بازرسی حافظه و ثبات‌ها، اجرای گام‌به‌گام، ارزیابی عبارات دلخواه در زمینه برنامه متوقف شده و اجرای اسکریپت‌های پایتون برای خودکارسازی. طبق داده‌های مخزن 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 Error Breakpoints و پارسر عبارات بهبودیافته برای Swift دریافت کرد. طبق داده‌های Apple، از iOS 14 به بعد، کل栈 دیباگ برای شبیه‌ساز نیز از طریق LLDB کار می‌کند که وضعیت آن را به عنوان ابزار اصلی دیباگ پلتفرم تأیید می‌کند.

معماری 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خط فرمان و حالت REPLliblldbInterpreter.dylib

LLDB و نمادهای دیباگ dSYM

dSYM — فایل‌های اطلاعات دیباگ هستند که Xcode هنگام کامپایل تولید می‌کند. LLDB از آنها برای تطبیق کد ماشین با کد منبع استفاده می‌کند: بدون dSYM دیباگر به جای نام توابع و خطوط کد، فقط آدرس‌های حافظه را نشان می‌دهد. برای اپلیکیشن‌های App Store، فایل‌های dSYM به طور جداگانه به سرور Apple آپلود می‌شوند و برای نمادسازی crash-logهای دریافت شده از کاربران از طریق CrashReporter استفاده می‌شوند.

lldb
(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 برای دیباگ

دستورات LLDB به چند دسته تقسیم می‌شوند: مدیریت اجرا، کار با breakpoints، بازرسی داده‌ها و دستکاری حافظه. برخلاف رابط گرافیکی Xcode، کنسول LLDB کنترل کامل بر دیباگ را فراهم می‌کند و امکان انجام عملیاتی را می‌دهد که از طریق رابط گرافیکی در دسترس نیستند — برای مثال، تغییر مقدار متغیر در لحظه یا ویرایش دسته‌ای breakpoints.

دستورات مدیریت اجرا

Continue, Step Over, Step Into, Step Out — اساس چرخه دیباگ هستند. continue اجرا را تا breakpoint بعدی از سر می‌گیرد. step over خط جاری را به طور کامل اجرا می‌کند. step into وارد متد فراخوانی‌شده می‌شود. step out تابع جاری را پایان می‌دهد و کنترل را به کد فراخوان بازمی‌گرداند. علاوه بر این، step with type filter وجود دارد — گام تا نوع داده مشخص‌شده.

lldb
(lldb) thread backtrace          # نمایش stack فراخوانی‌ها
* 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
(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 و po

دستور expression عبارت را در زمان اجرای فرآیند در حال دیباگ کامپایل و اجرا می‌کند. پرچم -O (object description) دستور po را فراخوانی می‌کند. برای عبارات چندخطی از expression -l Swift -- استفاده کنید. LLDB کد را در لحظه از طریق Clang یا Swift Compiler کامپایل می‌کند، نتیجه را در زمینه جاری ادغام کرده و مقدار را برمی‌گرداند. طبق داده‌های Apple، عبارت بسته به پیچیدگی در 10–50 میلی‌ثانیه کامپایل می‌شود.

lldb
(lldb) expr -l Swift -- UIAlertController(title: "Test", message: nil,
  preferredStyle: .alert)
(lldb) expr let $arr = [1, 2, 3].map { $0 * 2 }
(lldb) po $arr3 elements
  - 0 : 2
  - 1 : 4
  - 2 : 6

تغییر اشیاء در لحظه

LLDB نه تنها خواندن، بلکه تغییر وضعیت اشیاء و متغیرها را در حین دیباگ امکان‌پذیر می‌کند. این برای آزمایش موارد مرزی حیاتی است: می‌توان مقدار متغیر را به nil تنظیم کرد، رنگ عنصر UI را تغییر داد یا پاسخ سرور را مستقیماً در دیباگر جایگزین کرد، بدون کامپایل مجدد و راه‌اندازی مجدد. این تکنیک به طور گسترده در توسعه بازی‌ها و اپلیکیشن‌های با جریان طولانی استفاده می‌شود، جایی که راه‌اندازی مجدد زمان زیادی می‌برد.

lldb
(lldb) expr self.label.text = @"Updated"
(lldb) expr -l Swift -- (self as! UIViewController).view.backgroundColor = .red
(lldb) expr let $snapshot = self.view.debugQuickLookObject()

اسکریپت‌نویسی پایتون در LLDB

Python API LLDB امکان نوشتن اسکریپت‌هایی برای خودکارسازی دیباگ را فراهم می‌کند. از طریق پایتون می‌توان دستورات سفارشی ایجاد کرد، رویدادهای breakpoint را پردازش کرد، گزارش‌ها تولید کرد و حتی رفتار دیباگر را تغییر داد. مفسر داخلی پایتون 3 مستقیماً درون LLDB اجرا می‌شود و از طریق ماژول lldb به API کامل دیباگ دسترسی دارد.

ایجاد دستور سفارشی

می‌توان یک دستور جدید LLDB را از طریق دکوراتور @classmethod در اسکریپت پایتون ثبت کرد. پس از وارد کردن اسکریپت، دستور مانند یک دستور داخلی در دسترس می‌شود. برای مثال، دستور printvars می‌تواند تمام متغیرهای قاب جاری را با انواع و مقادیرشان، فرمت‌شده برای پروژه خاص، نمایش دهد. خودکارسازی زمان عملیات معمول دیباگ را 60–80٪ کاهش می‌دهد، طبق نظرسنجی توسعه‌دهندگان iOS در Stack Overflow.

python
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}")

پردازش رویدادهای breakpoints

از طریق Python API می‌توان یک اسکریپت را به فعال‌سازی breakpoint متصل کرد. breakpoint را تنظیم کنید، سپس breakpoint command add را اجرا کرده و تابع پایتون را مشخص کنید. این امکان ثبت خودکار وضعیت، ارسال داده‌ها به تحلیل یا بررسی تغییرناپذیری‌ها را بدون دخالت دستی فراهم می‌کند. طبق داده‌های LLVM، این رویکرد در زیرساخت Apple برای جمع‌آوری معیارهای عملکرد در مرحله توسعه استفاده می‌شود.

lldb
(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 و playground

REPL (Read-Eval-Print Loop) — حالت تعاملی LLDB که با دستور lldb --repl یا از طریق Xcode Debug Console فراخوانی می‌شود. در REPL می‌توان کد را به زبان Swift یا C مانند playground، با بازخورد فوری اجرا کرد. LLDB هر خط را کامپایل می‌کند، آن را اجرا کرده و نتیجه را نشان می‌دهد — این برای آزمایش با API، نمونه‌سازی اولیه الگوریتم‌ها و یادگیری قابلیت‌های جدید زبان بدون ایجاد پروژه مفید است.

lldb
(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 را بارگذاری می‌کند و می‌توان عناصر UI ایجاد کرد، constraintها را بررسی کرد و انیمیشن‌ها را تست کرد. این یک قابلیت منحصربه‌فرد برای توسعه‌دهندگان iOS است که در GDB وجود ندارد — دیباگ و نمونه‌سازی در یک محیط.

استفاده از REPL برای یادگیری Swift

به لطف یکپارچگی با Swift Compiler، LLDB REPL در دوره‌های Apple برای آموزش Swift استفاده می‌شود. دانشجویان می‌توانند کد را خط به خط اجرا کنند، انواع و نتایج را ببینند، بدون اینکه وقت خود را صرف تنظیم پروژه کنند. این رویکرد با روش Active Learning مطابقت دارد، جایی که بازخورد تعاملی طبق تحقیقات در زمینه Computer Science Education جذب مطالب را 40٪ تسریع می‌کند.

سوالات متداول

LLDB چه تفاوتی با GDB دارد؟

LLDB بر روی معماری ماژوالر LLVM ساخته شده است که به آن برتری در سرعت کار با عبارات و پشتیبانی از زبان‌های مدرن (Swift) می‌دهد. GDB — یک دیباگر یکپارچه است که از Swift پشتیبانی نمی‌کند و قابلیت‌های محدودی برای اسکریپت‌نویسی دارد.

چگونه LLDB REPL را روی macOS بدون Xcode اجرا کنیم؟

Command Line Tools را از طریق xcode-select --install نصب کنید، سپس lldb --repl را در ترمینال اجرا کنید. LLDB در /Library/Developer/CommandLineTools/usr/bin/ در دسترس است.

آیا می‌توان LLDB را به فرآیند در حال اجرا متصل کرد؟

بله، از طریق lldb --attach-pid PID یا process attach --name AppName. LLDB فرآیند را متوقف می‌کند و پس از آن تمام دستورات استاندارد دیباگ بدون راه‌اندازی مجدد اپلیکیشن در دسترس هستند.

چرا LLDB کد منبع را نشان نمی‌دهد و فقط اسمبلی نشان می‌دهد؟

فایل‌های dSYM اطلاعات دیباگ وجود ندارند. تنظیمات Build Settings را بررسی کنید: Generate Debug Symbols باید YES و Debug Information Format باید DWARF with dSYM File باشد.

چگونه تاریخچه دستورات LLDB را ذخیره کنیم؟

LLDB به طور خودکار تاریخچه را در ~/.lldb/lldb-history ذخیره می‌کند. برای خروجی از session save filename.txt استفاده کنید — این دستور تمام دستورات اجراشده جلسه جاری را در یک فایل متنی ذخیره می‌کند.

خلاصه

  • LLDB — دیباگر نسل جدید از پروژه LLVM، استاندارد برای Xcode و کل اکوسیستم Apple.
  • معماری ماژوالر با کتابخانه‌های Core، Expression Parser، Symbol File و Interpreter.
  • دستورات LLDB به مدیریت اجرا، breakpoints، بازرسی داده‌ها و ارزیابی عبارات تقسیم می‌شوند.
  • ارزیابی عبارات در لحظه — قابلیت کلیدی که امکان تست کد را بدون راه‌اندازی مجدد فراهم می‌کند.
  • Python API کنترل کامل بر دیباگر را از طریق اسکریپت‌ها فراهم می‌کند: دستورات سفارشی، پردازش breakpoints، گزارش‌ها.
  • حالت REPL به عنوان یک playground تعاملی برای Swift و C کار می‌کند که برای یادگیری و نمونه‌سازی مفید است.
  • فایل‌های dSYM برای نمادسازی crash-logها و نمایش صحیح کد منبع ضروری هستند.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید