LLVM-DEBUGINFO-ANALYZER(1) LLVM LLVM-DEBUGINFO-ANALYZER(1)

llvm-debuginfo-analyzer - چاپ نمایشی منطقی از اطلاعات اشکال‌زدایی سطح پایین.

  • خلاصه دستور (SYNOPSIS)
  • توضیحات (DESCRIPTION)
  • گزینه‌ها (OPTIONS)
  • عمومی (GENERAL)
  • مشخصه‌ها (ATTRIBUTES)
  • چاپ (PRINT)
  • خروجی (OUTPUT)
  • گزارش (REPORT)
  • گزینش (SELECTION)
  • عناصر (ELEMENTS)
  • خطوط (LINES)
  • حوزه‌ها (SCOPES)
  • نمادها (SYMBOLS)
  • نوع‌ها (TYPES)
  • مقایسه (COMPARE)
  • هشدار (WARNING)
  • داخلی (INTERNAL)
•
مثال‌ها (EXAMPLES)
•
مورد آزمون ۱ - گزینه‌های عمومی
•
حالت چاپ
  • جزئیات پایه
  • انتخاب عناصر منطقی
•
حالت مقایسه
  • نمای منطقی
  • عناصر منطقی
•
مورد آزمون ۲ - دستورالعمل‌های اسمبلی
  • CodeView - Clang (Windows)
  • CodeView - MSVC (Windows)
  • DWARF - Clang (Linux)
  • DWARF - GCC (Linux)
•
مورد آزمون ۳ - حوزه واژگانی نادرست برای TYPEDEF
  • CodeView - Clang (Windows)
  • CodeView - MSVC (Windows)
  • DWARF - Clang (Linux)
  • DWARF - GCC (Linux)
•
مورد آزمون ۴ - شمارش‌های تودرتوی مفقود
  • CodeView - Clang (Windows)
  • CodeView - MSVC (Windows)
  • DWARF - Clang (Linux)
  • DWARF - GCC (Linux)
•
مورد آزمون ۵ - حوزه واژگانی نادرست برای متغیر
  • CODEVIEW - Clang (Windows)
  • CODEVIEW - MSVC (Windows)
  • DWARF - Clang (Linux)
  • DWARF - GCC (Linux)
  • مورد آزمون ۶ - نمای منطقی کامل
  • پشتیبانی از WEBASSEMBLY
  • چاپ جزئیات پایه
  • گزینش عناصر منطقی
  • حالت مقایسه
  • نمای منطقی
  • عناصر منطقی
  • وضعیت خروج (EXIT STATUS)
  • محدودیت‌ها و مشکلات شناخته‌شده
  • همچنین ببینید (SEE ALSO)

    llvm-debuginfo-analyzer [options] [filename ...]

llvm-debuginfo-analyzer بخش‌های debug و text را در فایل‌های شیء دودویی (binary object files) تجزیه کرده و محتوای آن‌ها را در یک نمای منطقی (logical view) چاپ می‌کند؛ این نما بازنمایی خوانایی برای انسان است که تطابق نزدیکی با ساختار کد منبع اصلی کاربر دارد. قالب‌های فایل شیء پشتیبانی‌شده شامل ELF، Mach-O، WebAssembly، PDB و COFF هستند.

نمای منطقی پیچیدگی‌های مربوط به نمایش‌های گوناگون سطح پایین اطلاعات اشکال‌زداییِ تعبیه‌شده در فایل شیء را انتزاع می‌کند. llvm-debuginfo-analyzer صرف‌نظر از چگونگی قالب‌بندی اطلاعات اشکال‌زدایی، یک نمای استاندارد و متعارف (canonical) از آن تولید می‌کند. با فرض این‌که اطلاعات اشکال‌زدایی به‌درستی بیانگر همان کد منبع اصلی باشند، بدون در نظر گرفتن قالب فایل شیء، همان نمای منطقی یکسان مشاهده خواهد شد.

نمای منطقی شامل عناصر منطقی زیر است: type، scope، symbol و line که عناصر پایه‌ای نرم‌افزار مورد استفاده در زبان برنامه‌نویسی C/C++ هستند. هر عنصر منطقی دارای مجموعه‌ای از ویژگی‌ها (attributes) است، مانند types، classes، functions، variables، parameters و غیره. گزینهٔ --attribute می‌تواند برای مشخص کردن ویژگی‌هایی به کار رود که هنگام چاپ یک عنصر منطقی باید لحاظ شوند. یک عنصر منطقی ممکن است دارای یک kind باشد که انواع خاصی از عناصر را توصیف می‌کند؛ به عنوان مثال، یک scope می‌تواند دارای نوعِ (kind) function، class یا namespace باشد.

llvm-debuginfo-analyzer به‌طور پیش‌فرض چیدمان از پیش‌تعریف‌شده‌ای از عناصر و ویژگی‌های منطقی را چاپ می‌کند. از گزینه‌های خط فرمان می‌توان برای کنترل عناصر چاپ‌شده (--print)، استفاده از یک چیدمان مشخص (--report) و مطابقت با یک الگوی معین (--select، --select-offsets) استفاده کرد. همچنین خروجی را می‌توان با استفاده از (--select-lines، --select-scopes، --select-symbols، --select-types) به عناصر منطقی مشخص‌شده محدود نمود.

llvm-debuginfo-analyzer همچنین می‌تواند مجموعه‌ای از نماهای منطقی را با یکدیگر مقایسه کند (--compare) تا تفاوت‌ها را بیابد و خطاهای نحوی احتمالی در اطلاعات اشکال‌زدایی (--warning) را در هر فایل شیء شناسایی کند.

گزینه‌های llvm-debuginfo-analyzer به چند دسته تقسیم می‌شوند که هر یک برای هدف خاصی طراحی شده‌اند:

  • GENERAL - گزینه‌های استاندارد LLVM برای نمایش راهنما، نگارش و غیره.
  • ATTRIBUTES - توصیف چگونگی گنجاندن جزئیات مختلف هنگام چاپ یک عنصر.
  • PRINT - مشخص کردن این‌که کدام عناصر هنگام چاپ نما لحاظ شوند.
  • OUTPUT - توصیف قالب‌های پشتیبانی‌شده هنگام چاپ نما.
  • REPORT - توصیف چیدمان‌های قالب برای چاپ نما.
  • SELECTION - امکان استفاده از معیارها یا شرایط خاص برای انتخاب عناصر جهت چاپ.
  • COMPARE - مقایسهٔ نماهای منطقی و چاپ عناصر ناموجود یا اضافه‌شده.
  • WARNING - چاپ هشدارهای شناسایی‌شده در حین ایجاد نما.
  • INTERNAL - تحلیل داخلی نمای منطقی.

این بخش گزینه‌های استاندارد راهنما را شرح می‌دهد که برای نمایش نحوهٔ استفاده، نگارش، فایل‌های پاسخ (response files) و غیره به کار می‌روند.

نمایش راهنما و نحوهٔ استفاده از این دستور. (--help-hidden برای موارد بیشتر).
نمایش راهنما و نحوهٔ استفاده از این دستور بدون گروه‌بندی گزینه‌ها در دسته‌ها (--help-list-hidden برای موارد بیشتر).
نمایش تمام گزینه‌های موجود.
چاپ مقادیر تمام گزینه‌ها پس از تجزیهٔ خط فرمان.
چاپ گزینه‌های غیرپیش‌فرض پس از تجزیهٔ خط فرمان.
نمایش نگارش ابزار.
@<FILE>
خواندن گزینه‌های خط فرمان از <FILE>.

اگر هیچ فایل ورودی مشخص نشود، llvm-debuginfo-analyzer به‌طور پیش‌فرض a.out را می‌خواند و در صورتی که فایل ورودی پیدا نشود، خطایی بازمی‌گرداند.

اگر از - به عنوان فایل ورودی استفاده شود، llvm-debuginfo-analyzer ورودی را از جریان ورودی استاندارد خود می‌خواند..SS "مشخصه‌ها (ATTRIBUTES)"

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

که در آن value یکی از گزینه‌های موجود در فهرست‌های زیر است.
=all: شامل تمام مشخصه‌های زیر.
=extended: افزودن مشخصه‌های سطح پایین (low-level).
=standard: افزودن مشخصه‌های استاندارد سطح بالا (high-level).

مشخصه‌های زیر رایج‌ترین اطلاعات را برای یک عنصر منطقی توصیف می‌کنند. آن‌ها به شناسایی سطح حوزه لغوی (lexical scope level)، میزان دید عنصر در میان ماژول‌ها (سراسری، محلی)، نام زنجیره ابزار و زبان منبعی که فایل باینری را تولید کرده است کمک می‌کنند.

=global: عنصری که در چندین Compile Unit به آن ارجاع شده است.
=format: نام قالب فایل شیء (object file).
=language: نام زبان منبع (source language).
=level: سطح حوزه لغوی (File=0, Compile Unit=1).
=local: عنصری که فقط در همان Compile Unit به آن ارجاع شده است.
=producer: نام شناسایی زنجیره ابزار (toolchain).

مشخصه‌های زیر نام فایل‌ها و دایرکتوری‌ها را از کد منبع کاربر توصیف می‌کنند، جایی که عناصر در آن اعلان یا تعریف شده‌اند؛ همچنین توابعی با دید عمومی در میان ماژول‌ها. این گزینه‌ها امکان نگاشت عناصر به مکانشان در کد کاربر را برای اهداف ارجاع متقابل (cross reference) فراهم می‌کنند.

=directories: دایرکتوری‌های ارجاع‌داده‌شده در اطلاعات اشکال‌زدایی.
=filename: نام فایلی که عنصر در آن تعریف شده است.
=files: فایل‌های ارجاع‌داده‌شده در اطلاعات اشکال‌زدایی.
=pathname: نام مسیری که شیء در آن تعریف شده است.
=publics: نام توابعی که عمومی (public) هستند.

مشخصه‌های زیر تبدیلات اضافی سورس عنصر منطقی را توصیف می‌کنند، به‌منظور نمایش انواع توکار (int، bool، و غیره)؛ پارامترها و آرگومان‌های استفاده‌شده هنگام نمونه‌سازی الگو (template instantiation)؛ سلسله‌مراتب نام والد؛ اطلاعات ابعاد آرایه‌ها؛ عناصر تولیدشده توسط کامپایلر؛ اندازه انواع و انواع زیرین مرتبط با نام‌های مستعار انواع (type aliases).

=argument: پارامترهای الگو جایگزین‌شده با آرگومان‌های آن.
=base: انواع پایه (int, bool, etc.).
=generated: عناصر تولیدشده توسط کامپایلر.
=encoded: آرگومان‌های الگو که در نام الگو کدگذاری شده‌اند.
=qualified: نوع عنصر که نام والدین را در نام خود شامل می‌شود.
=reference: ارجاعات به اعلان و تعریف عنصر.
=size: اندازه‌ها برای انواع مرکب و پایه.
=subrange: اطلاعات کدگذاری زیردامنه (subrange) برای آرایه‌ها.
=typename: پارامترهای الگو (template).
=underlying: نوع زیرین برای تعریف نوع‌ها (type definitions).

مشخصه‌های زیر اطلاعات مکان اشکال‌زدایی (debug location) را برای یک نماد یا حوزه توصیف می‌کنند. این مشخصه‌ها شامل درصد پوشش نماد و هرگونه شکاف (gap) درون چیدمان مکان، و محدوده‌های تعیین‌کننده بخش‌های کد متصل به یک تابع هستند. هنگامی که از توصیف‌کننده‌ها استفاده شود، ثبات‌های پردازنده مقصد نمایش داده می‌شوند.

=coverage: درصد پوشش مکان نماد.
=gaps: مکان‌های اشکال‌زدایی ناموجود (شکاف‌ها).
=location: مکان اشکال‌زدایی نماد.
=range: محدوده‌های مکان اشکال‌زدایی.
=register: نام‌های ثبات‌های پردازنده.

مشخصه‌های زیر با جزئیات سطح پایین مرتبط هستند، از قبیل: آفست‌ها در فایل باینری؛ متمایزکننده‌ها (discriminators) افزوده شده به خطوط توابع درون‌خطی (inlined) برای تفکیک نمونه‌های خاص؛ ثبات‌های ماشین حالت خطوط اشکال‌زدایی؛ عناصر دور ریخته‌شده توسط کامپایلر (درون‌خطی‌سازی) یا بهینه‌سازی‌های پیونددهنده (حذف کدهای مرده یا dead-stripping)؛ واحدهای کامپایل سیستمی تولیدشده توسط زنجیره ابزار MS در PDBها.

=discarded: عناصر دور ریخته‌شده توسط پیونددهنده (linker).
=discriminator: متمایزکننده‌ها برای نمونه‌های توابع درون‌خطی (inlined).
=inserted: ارجاعات انتزاعی درون‌خطی تولیدشده.
=linkage: نام پیوند (linkage) در فایل شیء.
=offset: آفست اطلاعات اشکال‌زدایی.
=qualifier: توصیف‌کننده‌های خط (Newstatement, BasicBlock, etc).
=zero: شماره خط‌های صفر.

مشخصه زیر اطلاعات خاص مربوط به قالب فایل PE/COFF را توصیف می‌کند. این مشخصه شامل انواع زمان اجرای MS است.

=system: نمایش عناصر سیستمی MS مربوط به PDBها.

مشخصه‌های بالا در دسته‌های standard و extended گروه‌بندی شده‌اند که می‌توان آن‌ها را فعال کرد.

گروه standard شامل مشخصه‌هایی است که اطلاعات کافی برای توصیف یک عنصر منطقی اضافه می‌کنند و می‌توانند موقعیت‌های عادی را در هنگام کار با اطلاعات اشکال‌زدایی پوشش دهند.

=base
=coverage
=directories
=discriminator
=filename
=files
=format
=language
=level
=producer
=publics
=range
=reference
=zero

گروه extended شامل مشخصه‌هایی است که نیازمند دانش عمیق‌تری درباره اطلاعات اشکال‌زدایی هستند. این مشخصه‌ها زمانی کاربرد دارند که سطح پایین‌تر و دقیق‌تری از جزئیات مورد نیاز باشد.

=argument
=discarded
=encoded
=gaps
=generated
=global
=inserted
=linkage
=local
=location
=offset
=operation
=pathname
=qualified
=qualifier
=register
=size
=subrange
=system
=typename

گزینه‌های زیر عنصرهایی را که باید چاپ شوند توصیف می‌کنند. چیدمان مورد استفاده توسط --report مشخص می‌شود. در چیدمان درختی، تمام عنصرها حوزه‌های لغوی دربرگیرنده خود را چاپ می‌کنند، حتی زمانی که به‌طور صریح مشخص نشده باشند.

که در آن value یکی از گزینه‌های فهرست‌های زیر است.
=all: تمام ویژگی‌های زیر را شامل می‌شود.

گزینه‌های زیر عنصرهای درخواستی را چاپ می‌کنند؛ در صورت تعیین هرگونه شرایط انتخاب (--select)، تنها عنصرهایی که با آن‌ها مطابقت داشته باشند چاپ خواهند شد. مقدار elements روشی مناسب برای مشخص کردن هم‌زمان دستورالعمل‌ها، خطوط، حوزه‌ها، نمادها و انواع است.

=elements: دستورالعمل‌ها، خطوط، حوزه‌ها، نمادها و انواع.
=instructions: دستورالعمل‌های اسمبلی برای بخش‌های کد.
=lines: خطوط مبدأ ارجاع داده‌شده در اطلاعات اشکال‌زدایی.
=scopes: بلوک‌های لغوی (تابع، کلاس، فضای نام و غیره).
=symbols: نمادها (متغیر، عضو، پارامتر و غیره).
=types: انواع (اشاره‌گر، ارجاع، نام مستعار نوع و غیره).

گزینه‌های زیر اطلاعات جمع‌آوری‌شده در حین ایجاد عنصرها را چاپ می‌کنند، از قبیل: سهم حوزه‌ها در اطلاعات اشکال‌زدایی؛ خلاصه عنصرهای ایجادشده، چاپ‌شده یا تطبیق‌یافته (--select)؛ هشدارهای تولیدشده در حین ایجاد نما.

=sizes: سهم حوزه‌ها در اطلاعات اشکال‌زدایی.
=summary: خلاصه عنصرهای تخصیص‌یافته، انتخاب‌شده یا چاپ‌شده.
=warnings: هشدارهای شناسایی‌شده.

نکته: گزینه --print=sizes مختص ELF است.

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

تغییر مسیر خروجی به فایلی که با <path> مشخص می‌شود، که در آن - نشان‌دهنده جریان خروجی استاندارد است.

دستور llvm-debuginfo-analyzer دارای مفهوم «نمای تفکیک‌شده» (split view) است. هنگام تغییر مسیر خروجی از یک قالب باینری پیچیده، خروجی به فایل‌های مجزا تقسیم می‌شود که هر کدام شامل خروجی نمای منطقی برای یک واحد ترجمه (compilation unit) مجزا است.

پوشه‌ای برای نوشتن یک فایل به ازای هر واحد ترجمه، در صورتی که --output=split مشخص شده باشد.
تنها عنصرهایی را چاپ می‌کند که تا مقدار سطح لغوی (lexical level) مشخص‌شده باشند. فایل ورودی در سطح لغوی صفر و یک واحد ترجمه در سطح لغوی یک قرار دارد.
که در آن value یکی از گزینه‌های فهرست‌های زیر است.
=all: تمام خروجی‌های زیر را شامل می‌شود.
=json: استفاده از JSON به عنوان قالب خروجی (پیاده‌سازی نشده است).
=split: تفکیک خروجی بر اساس واحدهای ترجمه (Compile Units).
=text: استفاده از خروجی متنی با فرم آزاد.
کلید اصلی هنگام مرتب‌سازی عنصرها در خروجی (پیش‌فرض: line). مرتب‌سازی بر اساس نوع عنصر منطقی، مستلزم آشنایی با گزینه‌های انتخاب نوع عنصر (--select-lines، --select-scopes، --select-symbols، --select-types) است، زیرا آن گزینه‌ها انواع مختلف عنصرهای منطقی را توصیف می‌کنند.
=none: خروجی بدون مرتب‌سازی (همان‌گونه که از ورودی خوانده شده است).
=id: مرتب‌سازی بر اساس شناسه یکتای عنصر.
=kind: مرتب‌سازی بر اساس نوع عنصر.
=line: مرتب‌سازی بر اساس شماره خط عنصر.
=name: مرتب‌سازی بر اساس نام عنصر.
=offset: مرتب‌سازی بر اساس آفست عنصر.

بسته به وظیفه‌ای که اجرا می‌شود (print،‏ compare،‏ select)، چندین طرح‌بندی برای نمایش عناصر به شکلی مناسب‌تر پشتیبانی می‌شوند تا درک خروجی آسان‌تر گردد.

به‌طوری‌که value یکی از گزینه‌های فهرست زیر باشد.
=all: شامل تمام گزارش‌های زیر.
=children: عناصر و فرزندان در قالب درختی نمایش داده می‌شوند.
=list: عناصر در قالب جدولی نمایش داده می‌شوند.
=parents: عناصر و والدین در قالب درختی نمایش داده می‌شوند.
=view: عناصر، والدین و فرزندان در قالب درختی نمایش داده می‌شوند.

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

طرح‌بندی‌های children، parents و view عناصر را در یک قالب درختی نمایش می‌دهند؛ به‌طوری‌که حوزه‌ها (scopes) گره‌های آن، و انواع (types)، نمادها (symbols)، خطوط (lines) و سایر حوزه‌ها فرزندان آن‌ها را تشکیل می‌دهند. این طرح‌بندی، رابطهٔ حوزهٔ واژگانی (lexical scoping) میان عناصر را نشان می‌دهد که در آن فایل باینری ریشهٔ درخت (سطح 0) و هر واحد ترجمه (compilation unit) یک فرزند (سطح 1) است.

طرح‌بندی children شامل عناصری است که با هر یک از معیارهای تعیین‌شده (--select) یا (--compare) مطابقت دارند، به همراه فرزندان آن‌ها.

طرح‌بندی parents شامل عناصری است که با هر یک از معیارهای تعیین‌شده (--select) یا (--compare) مطابقت دارند، به همراه والدین آن‌ها.

طرح‌بندی ترکیبی view شامل عناصری است که با هر یک از معیارهای تعیین‌شده (--select) یا (--compare) مطابقت دارند، به همراه والدین و فرزندان آن‌ها.

نکات:

1.
هنگامی که یک معیار گزینش (--select) بدون مشخص کردن گزینهٔ گزارش تعیین شود، طرح‌بندی list انتخاب می‌شود.
2.
حالت مقایسه همواره از طرح‌بندی view استفاده می‌کند.

هنگام چاپ یک عنصر، داده‌های گوناگونی را می‌توان لحاظ کرد و این اطلاعات (--attribute) از داده‌های مستقیماً مرتبط با فایل باینری (افست) گرفته تا جزئیات سطح بالا مانند پوشش، سطح حوزهٔ واژگانی و مکان را در بر می‌گیرد. با توجه به اینکه خروجی چاپ‌شده ممکن است به اندازهٔ قابل‌توجهی برسد، چندین گزینهٔ گزینش، امکان چاپ عناصری مشخص را فراهم می‌کنند.

تطبیق الگو می‌تواند به حروف کوچک و بزرگ حساس نباشد (--select-nocase) و برای استفاده از عبارات باقاعده گسترش یابد (--select-regex).

گزینه‌های زیر امکان چاپ عناصری را فراهم می‌کنند که با <pattern>، مقدار <value> افست یا یک <condition> عنصر داده‌شده مطابقت دارند.

چاپ تمام عناصری که نام یا شماره خط آن‌ها با <pattern> داده‌شده مطابقت دارد.
چاپ تمام عناصری که افست آن‌ها با مقادیر داده‌شده مطابقت دارد. گزینهٔ --attribute را ببینید.
چاپ تمام عناصری که <condition> داده‌شده را برآورده می‌کنند؛ به‌طوری‌که condition یکی از گزینه‌های فهرست زیر باشد.
=discarded: عناصر کنار گذاشته‌شده توسط پیونددهنده (linker).
=global: عنصری که در چندین واحد ترجمه به آن ارجاع داده شده است.
=optimized: ارجاعات انتزاعی درون‌خطی‌شدهٔ بهینه‌سازی‌شده.
هنگام استفاده از --select، تطبیق الگو به حروف بزرگ و کوچک حساس نیست.
هنگام گزینش با گزینهٔ --select، با هر رشتهٔ <pattern> به عنوان یک عبارت باقاعده رفتار می‌کند. اگر --select-nocase مشخص شده باشد، عبارت باقاعده به حروف بزرگ و کوچک حساس نخواهد بود.

اگر معیار <pattern> بیش از حد عمومی باشد، می‌توان گزینهٔ دقیق‌تری را برای هدف قرار دادن دسته‌بندی خاصی از عناصر تعیین کرد: خطوط (--select-lines)، حوزه‌ها (--select-scopes)، نمادها (--select-symbols) و انواع (--select-types).

این گزینه‌ها نیازمند آگاهی از قالب اطلاعات اشکال‌زدایی (DWARF،‏ CodeView) هستند، زیرا kind داده‌شده، نوع بسیار خاصی از عناصر را توصیف می‌کند..SS "سطرها (LINES)"

گزینه‌های زیر امکان چاپ سطرهایی را فراهم می‌کنند که با <kind> داده‌شده مطابقت دارند. معیار ارائه‌شده، ثبات‌های ماشین حالت debug line را توصیف می‌کند.

به‌طوری که kind یکی از گزینه‌های فهرست زیر باشد.
=AlwaysStepInto: یک پرش همیشگی به درون (always step into) را علامت‌گذاری می‌کند.
=BasicBlock: یک بلوک پایه‌ای (basic block) جدید را علامت‌گذاری می‌کند.
=Discriminator: سطری که دارای یک تفکیک‌کننده (discriminator) است.
=EndSequence: پایان توالی سطرها را علامت‌گذاری می‌کند.
=EpilogueBegin: آغاز بخش پایانی (epilogue) تابع را علامت‌گذاری می‌کند.
=LineAssembler: سطرهایی که متناظر با متن دیس‌اسمبلی هستند.
=LineDebug: سطرهایی که متناظر با سطرهای اشکال‌زدایی (debug lines) هستند.
=NeverStepInto: یک عدم پرش به درون (never step into) را علامت‌گذاری می‌کند.
=NewStatement: یک عبارت (statement) جدید را علامت‌گذاری می‌کند.
=PrologueEnd: پایان بخش آغازین (prologue) تابع را علامت‌گذاری می‌کند.

گزینه‌های زیر امکان چاپ حوزه‌هایی را فراهم می‌کنند که با <kind> داده‌شده مطابقت دارند.

به‌طوری که kind یکی از گزینه‌های فهرست زیر باشد.
=Aggregate: یک کلاس، ساختار یا اجتماع (union).
=Array: یک آرایه.
=Block: یک بلوک عمومی (بلوک واژگانی یا بلوک استثنا).
=CallSite: یک محل فراخوانی (call site).
=CatchBlock: یک بلوک استثنا (catch block).
=Class: یک کلاس.
=CompileUnit: یک واحد کامپایل (compile unit).
=EntryPoint: یک نقطهٔ ورود زیرروال (subroutine).
=Enumeration: یک شمارش (enumeration).
=Function: یک تابع.
=FunctionType: یک اشاره‌گر تابع (function pointer).
=InlinedFunction: یک تابع درون‌خطی (inlined function).
=Label: یک برچسب (label).
=LexicalBlock: یک بلوک واژگانی (lexical block).
=Module: یک ماژول.
=Namespace: یک فضای نام (namespace).
=Root: عنصری که نمایانگر حوزهٔ اصلی (main scope) است.
=Structure: یک ساختار (structure).
=Subprogram: یک زیربرنامه (subprogram).
=Template: یک تعریف الگو (template).
=TemplateAlias: یک نام مستعار الگو (template alias).
=TemplatePack: یک بسته الگو (template pack).
=TryBlock: یک بلوک استثنای try.
=Union: یک اجتماع (union).

گزینه‌های زیر امکان چاپ نمادهایی را فراهم می‌کنند که با <kind> داده‌شده مطابقت دارند.

به‌طوری که kind یکی از گزینه‌های فهرست زیر باشد.
=CallSiteParameter: یک پارامتر محل فراخوانی (call site).
=Constant: یک نماد ثابت (constant).
=Inheritance: یک کلاس پایه (base class).
=Member: یک کلاس عضو (member class).
=Parameter: یک پارامتر برای تابع.
=Unspecified: پارامترهای نامشخص برای تابع.
=Variable: یک متغیر.

گزینه‌های زیر امکان چاپ نوع‌هایی را فراهم می‌کنند که با <kind> مشخص‌شده مطابقت دارند.

به طوری که kind یکی از گزینه‌های فهرست زیر باشد:
=Base: نوع پایه (عدد صحیح، بولی و غیره).
=Const: مشخص‌گر ثابت (const).
=Enumerator: مقدار شمارشی (Enumerator).
=Import: اعلان واردسازی (import).
=ImportDeclaration: اعلان واردسازی.
=ImportModule: ماژول واردسازی.
=Pointer: نوع اشاره‌گر.
=PointerMember: اشاره‌گر به تابع عضو.
=Reference: نوع مرجع.
=Restrict: مشخص‌گر restrict.
=RvalueReference: مرجع مقدار راست (R-value reference).
=Subrange: زیربازه آرایه.
=TemplateParam: پارامتر الگو.
=TemplateTemplateParam: پارامتر الگوی الگو.
=TemplateTypeParam: پارامتر نوع الگو.
=TemplateValueParam: پارامتر مقدار الگو.
=Typedef: تعریف نوع (typedef).
=Unspecified: نوع مشخص‌نشده.
=Volatile: مشخص‌گر فرار (volatile).

هنگام کار با اطلاعات اشکال‌زدایی (debug information)، موقعیت‌هایی وجود دارد که چاپ صرف عناصر، رویکرد مناسبی نیست. این حالت زمانی رخ می‌دهد که بررسی تأثیرات ناشی از نسخه‌های مختلف یک زنجیره‌ابزار یکسان، یا اثر بهینه‌سازی‌های خاص کامپایلر مد نظر باشد.

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

ابزار llvm-debuginfo-analyzer از مقایسه منطقی عناصر پشتیبانی می‌کند که امکان یافتن تفاوت‌های معنایی بین نماهای منطقیِ تولیدشده توسط نسخه‌های مختلف زنجیره‌ابزار یا حتی قالب‌های اطلاعات اشکال‌زدایی گوناگون را فراهم می‌سازد.

هنگام مقایسه نماهای منطقیِ ایجادشده از قالب‌های اشکال‌زدایی متفاوت، دقت مقایسه به این بستگی دارد که اطلاعات اشکال‌زدایی تا چه اندازه کد کاربر را دقیق بازنمایی می‌کنند. به عنوان مثال، یک نمای منطقی ایجادشده از یک فایل باینری با اطلاعات اشکال‌زدایی DWARF ممکن است شامل داده‌های دقیق‌تری نسبت به یک نمای منطقی ایجادشده از یک فایل باینری با اطلاعات اشکال‌زدایی CodeView باشد.

گزینه‌های زیر عناصر مورد مقایسه را شرح می‌دهند.

به طوری که value یکی از گزینه‌های فهرست زیر باشد:
=all: شامل تمام عناصر زیر.
=lines: شامل خط‌ها.
=scopes: شامل حوزه‌ها.
=symbols: شامل نمادها.
=types: شامل انواع.

ابزار llvm-debuginfo-analyzer نخستین فایل باینری در خط فرمان را به عنوان reference (مرجع) و فایل دوم را به عنوان target (هدف) در نظر می‌گیرد. برای دستیابی به گزارشی توصیفی‌تر، مقایسه دو بار انجام می‌شود. نماهای مرجع و هدف جابه‌جا می‌شوند تا آن دسته از عناصر missing (مفقود) از نمای هدف و عناصر added (افزوده‌شده) به نمای مرجع مشخص شوند.

برای چگونگی شرح گزارش‌های مقایسه، گزینه‌های --report را ببینید..SS "هشدار (WARNING)"

هنگام خواندن فایل‌های شیء ورودی، llvm-debuginfo-analyzer می‌تواند مشکلاتی را در اطلاعات اشکال‌زدایی خام شناسایی کند. ممکن است این موارد برای هدفِ چاپ یک نمای منطقی مهلک تلقی نشوند، اما می‌توانند نشانه‌ای از کیفیت بوده و به‌طور بالقوه مشکلاتی را در اطلاعات اشکال‌زدایی تولیدشده آشکار سازند.

گزینه‌های زیر هشدارهایی را شرح می‌دهند که در صورت درخواست توسط --print، برای چاپ بعدی ثبت می‌شوند.

که در آن value یکی از گزینه‌های فهرست زیر است.
=all: شامل تمام هشدارهای زیر.

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

=coverages: مقادیر نامعتبر پوشش نماد.
=lines: خطوط اشکال‌زدایی با مقدار صفر.
=locations: مکان‌های نامعتبر نماد.
=ranges: محدوده‌های نامعتبر کد.

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

llvm-debuginfo-analyzer از این گزینه‌های پیشرفته در هر دو ساخت release و debug پشتیبانی می‌کند.

که در آن value یکی از گزینه‌های فهرست زیر است.
=all: شامل تمام گزینه‌های زیر.

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

=id: چاپ شناسه یکتای عنصر.
=cmdline: چاپ خط فرمان.
=integrity: بررسی یکپارچگی عناصر.
=none: نادیده گرفتن شماره خط عنصر.
=tag: برچسب‌های اطلاعات اشکال‌زدایی.

نکته: برای قالب ELF، برچسب‌های جمع‌آوری‌شده نشان‌دهنده برچسب‌های اشکال‌زدایی هستند که پردازش نشده‌اند. برای قالب PE/COFF، آن‌ها نشان‌دهنده برچسب‌هایی هستند که پردازش شده‌اند.

این بخش شامل چند فایل باینری واقعی است تا نحوه استفاده از llvm-debuginfo-analyzer را برای چاپ یک نمای منطقی و تشخیص مشکلات احتمالی اطلاعات اشکال‌زدایی نشان دهد.

مثال زیر برای نشان دادن خروجی‌های متفاوتی که توسط llvm-debuginfo-analyzer تولید می‌شود به کار رفته است. ما این مثال را برای یک هدف X86 ELF با Clang (-O0 -g) کامپایل کرده‌ایم:

1  using INTPTR = const int *;
2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
3    if (ParamBool) {
4      typedef int INTEGER;
5      const INTEGER CONSTANT = 7;
6      return CONSTANT;
7    }
8    return ParamUnsigned;
9  }

در این حالت llvm-debuginfo-analyzer نمای منطقی یا بخش‌هایی از آن را بر اساس الگوهای معیار (شامل عبارات باقاعده) برای انتخاب نوع عناصر منطقی که باید در خروجی گنجانده شوند، چاپ می‌کند.

دستور زیر جزئیات پایه‌ای را برای تمام عناصر منطقی مرتب‌شده بر اساس آفست داخلی اطلاعات اشکال‌زدایی چاپ می‌کند؛ این شامل سطح واژگانی (lexical level) و قالب اطلاعات اشکال‌زدایی آن است.

llvm-debuginfo-analyzer --attribute=level,format
                        --output-sort=offset
                        --print=scopes,symbols,types,lines,instructions
                        test-dwarf-clang.o

یا

llvm-debuginfo-analyzer --attribute=level,format
                        --output-sort=offset
                        --print=elements
                        test-dwarf-clang.o

هر ردیف نشان‌دهنده عنصری است که در اطلاعات اشکال‌زدایی وجود دارد. ستون نخست نشان‌دهنده سطح دامنه (scope level) است که پس از آن شماره خط مربوطه (در صورت وجود) و در نهایت شرح عنصر می‌آید.

Logical View:
[000]           {File} 'test-dwarf-clang.o' -> elf64-x86-64
[001]             {CompileUnit} 'test.cpp'
[002]     2         {Function} extern not_inlined 'foo' -> 'int'
[003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
[003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
[003]     2           {Parameter} 'ParamBool' -> 'bool'
[003]                 {Block}
[004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
[004]     5             {Line}
[004]                   {Code} 'movl  $0x7, -0x1c(%rbp)'
[004]     6             {Line}
[004]                   {Code} 'movl  $0x7, -0x4(%rbp)'
[004]                   {Code} 'jmp   0x6'
[004]     8             {Line}
[004]                   {Code} 'movl  -0x14(%rbp), %eax'
[003]     4           {TypeAlias} 'INTEGER' -> 'int'
[003]     2           {Line}
[003]                 {Code} 'pushq   %rbp'
[003]                 {Code} 'movq    %rsp, %rbp'
[003]                 {Code} 'movb    %dl, %al'
[003]                 {Code} 'movq    %rdi, -0x10(%rbp)'
[003]                 {Code} 'movl    %esi, -0x14(%rbp)'
[003]                 {Code} 'andb    $0x1, %al'
[003]                 {Code} 'movb    %al, -0x15(%rbp)'
[003]     3           {Line}
[003]                 {Code} 'testb   $0x1, -0x15(%rbp)'
[003]                 {Code} 'je      0x13'
[003]     8           {Line}
[003]                 {Code} 'movl    %eax, -0x4(%rbp)'
[003]     9           {Line}
[003]                 {Code} 'movl    -0x4(%rbp), %eax'
[003]                 {Code} 'popq    %rbp'
[003]                 {Code} 'retq'
[003]     9           {Line}
[002]     1         {TypeAlias} 'INTPTR' -> '* const int'

با بررسی دقیق‌تر، می‌توانیم ببینیم چه چیزی می‌تواند یک مشکل بالقوه در اشکال‌زدایی باشد:

[003]                 {Block}
[003]     4           {TypeAlias} 'INTEGER' -> 'int'

تعریف 'INTEGER' در سطح [003] است، یعنی همان دامنه واژگانی {Block} ناشناس (شاخه 'true' برای دستور 'if')، در حالی که در کد منبع اصلی دستور typedef مشخصاً درون آن بلوک قرار دارد؛ بنابراین تعریف 'INTEGER' نیز باید در سطح [004] در داخل بلوک باشد..SS "انتخاب عناصر منطقی (SELECT LOGICAL ELEMENTS)"

دستور زیر تمام instructions، symbols و types که حاوی 'inte' یا 'movl' در نام یا نوع خود هستند را با استفاده از قالب‌بندی ستونی (tab layout) و با نمایش تعداد موارد منطبق، چاپ می‌کند.

llvm-debuginfo-analyzer --attribute=level
                        --select-nocase --select-regex
                        --select=INTe --select=movl
                        --report=list
                        --print=symbols,types,instructions,summary
                        test-dwarf-clang.o
Logical View:
[000]           {File} 'test-dwarf-clang.o'
[001]           {CompileUnit} 'test.cpp'
[003]           {Code} 'movl  $0x7, -0x1c(%rbp)'
[003]           {Code} 'movl  $0x7, -0x4(%rbp)'
[003]           {Code} 'movl  %eax, -0x4(%rbp)'
[003]           {Code} 'movl  %esi, -0x14(%rbp)'
[003]           {Code} 'movl  -0x14(%rbp), %eax'
[003]           {Code} 'movl  -0x4(%rbp), %eax'
[003]     4     {TypeAlias} 'INTEGER' -> 'int'
[004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
-----------------------------
Element      Total      Found
-----------------------------
Scopes           3          0
Symbols          4          1
Types            2          1
Lines           17          6
-----------------------------
Total           26          8

در این حالت، llvm-debuginfo-analyzer نماهای منطقی (logical views) را برای ایجاد گزارشی از عناصر منطقیِ مفقود یا اضافه‌شده مقایسه می‌کند. این قابلیت یک ابزار بسیار قدرتمند برای یافتن تفاوت‌های معنایی در اطلاعات اشکال‌زدایی تولیدشده توسط نسخه‌های مختلف زنجیره ابزار (toolchain) یا حتی زنجیره‌های ابزار کاملاً متفاوت است (به عنوان مثال، کامپایلری که DWARF تولید می‌کند را می‌توان مستقیماً با کامپایلر کاملاً متفاوتی که CodeView تولید می‌کند مقایسه کرد).

با توجه به مثال قبلی، ما با مقایسه در برابر یک کامپایلر دیگر، مشکل اطلاعات اشکال‌زدایی فوق (مربوط به مکان نامعتبر قبلی حوزه برای 'typedef int INTEGER') را شناسایی کردیم.

با استفاده از GCC برای تولید test-dwarf-gcc.o، می‌توانیم یک الگوی گزینش را همراه با حالت چاپ اعمال کنیم تا خروجی نمای منطقی زیر به دست آید.

llvm-debuginfo-analyzer --attribute=level
                        --select-regex --select-nocase --select=INTe
                        --report=list
                        --print=symbols,types
                        test-dwarf-clang.o test-dwarf-gcc.o
Logical View:
[000]           {File} 'test-dwarf-clang.o'
[001]           {CompileUnit} 'test.cpp'
[003]     4     {TypeAlias} 'INTEGER' -> 'int'
[004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
Logical View:
[000]           {File} 'test-dwarf-gcc.o'
[001]           {CompileUnit} 'test.cpp'
[004]     4     {TypeAlias} 'INTEGER' -> 'int'
[004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'

خروجی نشان می‌دهد که هر دو شیء شامل عناصر یکسانی هستند، اما 'typedef INTEGER' در سطح حوزه (scope level) متفاوتی قرار دارد. شیء تولیدشده توسط GCC مقدار '4' را نشان می‌دهد که مقدار صحیح است.

توجه داشته باشید که برای انجام مقایسه، الزامی مبنی بر اینکه GCC حتماً باید DWARF یکسان یا مشابهی با Clang تولید کند وجود ندارد. ما تنها معناشناسی (semantics) را مقایسه می‌کنیم. همین موضوع هنگام مقایسه اطلاعات اشکال‌زدایی CodeView تولیدشده توسط MSVC و Clang نیز صدق می‌کند.

۲ روش برای مقایسه وجود دارد: نمای منطقی (logical view) و عناصر منطقی (logical elements)..SS "نمای منطقی (LOGICAL VIEW)"

این بخش نمای منطقی را به‌عنوان یک کلِ واحد مقایسه می‌کند؛ برای برقراری تطابق، هر عنصر منطقیِ مقایسه‌شده باید والدین و فرزندان یکسانی داشته باشد.

با استفاده از قابلیت مقایسه llvm-debuginfo-analyzer، می‌توان آن مسئله را در بستری کلی‌تر که می‌تواند شامل نمای منطقی نیز باشد، مشاهده کرد.

خروجی در قالب نما، عناصر مفقود (-) و افزوده‌شده (+) را نشان می‌دهد، و با جابه‌جا کردن فایل‌های شیءِ مرجع و هدف، زمینه بیشتری فراهم می‌کند.

llvm-debuginfo-analyzer --attribute=level
                        --compare=types
                        --report=view
                        --print=symbols,types
                        test-dwarf-clang.o test-dwarf-gcc.o
Reference: 'test-dwarf-clang.o'
Target:    'test-dwarf-gcc.o'
Logical View:
 [000]           {File} 'test-dwarf-clang.o'
 [001]             {CompileUnit} 'test.cpp'
 [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 [002]     2         {Function} extern not_inlined 'foo' -> 'int'
 [003]                 {Block}
 [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
+[004]     4             {TypeAlias} 'INTEGER' -> 'int'
 [003]     2           {Parameter} 'ParamBool' -> 'bool'
 [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
 [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
-[003]     4           {TypeAlias} 'INTEGER' -> 'int'

خروجی، مسیر نمای ادغام‌شده (مرجع و هدف) را به همراه عناصر مفقود و افزوده‌شده نمایش می‌دهد.

این بخش عناصر منطقی را به‌صورت مجزا و بدون در نظر گرفتن یکسان بودن والدین آن‌ها مقایسه می‌کند. برای هر دو روش مقایسه، معیارهای برابری شامل نام، مکان در کد منبع، نوع و سطح حوزه واژگانی (lexical scope level) است.

llvm-debuginfo-analyzer --attribute=level
                        --compare=types
                        --report=list
                        --print=symbols,types,summary
                        test-dwarf-clang.o test-dwarf-gcc.o
Reference: 'test-dwarf-clang.o'
Target:    'test-dwarf-gcc.o'
(1) Missing Types:
-[003]     4     {TypeAlias} 'INTEGER' -> 'int'
(1) Added Types:
+[004]     4     {TypeAlias} 'INTEGER' -> 'int'
----------------------------------------
Element   Expected    Missing      Added
----------------------------------------
Scopes           4          0          0
Symbols          0          0          0
Types            2          1          1
Lines            0          0          0
----------------------------------------
Total            6          1          1

تغییر ترتیب Reference و Target:

llvm-debuginfo-analyzer --attribute=level
                        --compare=types
                        --report=list
                        --print=symbols,types,summary
                        test-dwarf-gcc.o test-dwarf-clang.o
Reference: 'test-dwarf-gcc.o'
Target:    'test-dwarf-clang.o'
(1) Missing Types:
-[004]     4     {TypeAlias} 'INTEGER' -> 'int'
(1) Added Types:
+[003]     4     {TypeAlias} 'INTEGER' -> 'int'
----------------------------------------
Element   Expected    Missing      Added
----------------------------------------
Scopes           4          0          0
Symbols          0          0          0
Types            2          1          1
Lines            0          0          0
----------------------------------------
Total            6          1          1

با جابه‌جا شدن Reference و Target، موارد Added Types از حالت اول، اکنون در قالب Missing Types فهرست می‌شوند..SS "مورد آزمایشی ۲ - دستورالعمل‌های اسمبلی (TEST CASE 2 - ASSEMBLER INSTRUCTIONS)"

مثال زیر برای نشان دادن خروجی‌های متفاوتی که توسط llvm-debuginfo-analyzer تولید می‌شوند، به کار رفته است. ما این مثال را برای هدف‌های X86 Codeview و ELF با نسخه‌های اخیر Clang، GCC و MSVC (-O0 -g) برای Windows و Linux کامپایل کرده‌ایم.

1  extern int printf(const char * format, ... );
2
3  int main()
4  {
5    printf("Hello, World\n");
6    return 0;
7  }

این‌ها نماهای منطقی‌ای هستند که llvm-debuginfo-analyzer برای ۳ کامپایلر مختلف (MSVC، Clang و GCC) تولید می‌کند که قالب‌های اطلاعات اشکال‌زدایی متفاوتی (CodeView، DWARF) را در Windows و Linux صادر می‌کنند.

llvm-debuginfo-analyzer --attribute=level,format,producer
                        --print=lines,instructions
                        hello-world-codeview-clang.o
                        hello-world-codeview-msvc.o
                        hello-world-dwarf-clang.o
                        hello-world-dwarf-gcc.o

Logical View:
[000]           {File} 'hello-world-codeview-clang.o' -> COFF-x86-64
[001]             {CompileUnit} 'hello-world.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]               {Function} extern not_inlined 'main' -> 'int'
[003]     4           {Line}
[003]                 {Code} 'subq    $0x28, %rsp'
[003]                 {Code} 'movl    $0x0, 0x24(%rsp)'
[003]     5           {Line}
[003]                 {Code} 'leaq    (%rip), %rcx'
[003]                 {Code} 'callq   0x0'
[003]     6           {Line}
[003]                 {Code} 'xorl    %eax, %eax'
[003]                 {Code} 'addq    $0x28, %rsp'
[003]                 {Code} 'retq'

Logical View:
[000]           {File} 'hello-world-codeview-msvc.o' -> COFF-i386
[001]             {CompileUnit} 'hello-world.cpp'
[002]               {Producer} 'Microsoft (R) Optimizing Compiler'
[002]               {Function} extern not_inlined 'main' -> 'int'
[003]     4           {Line}
[003]                 {Code} 'pushl   %ebp'
[003]                 {Code} 'movl    %esp, %ebp'
[003]     5           {Line}
[003]                 {Code} 'pushl   $0x0'
[003]                 {Code} 'calll   0x0'
[003]                 {Code} 'addl    $0x4, %esp'
[003]     6           {Line}
[003]                 {Code} 'xorl    %eax, %eax'
[003]     7           {Line}
[003]                 {Code} 'popl    %ebp'
[003]                 {Code} 'retl'
Logical View:
[000]           {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64
[001]             {CompileUnit} 'hello-world.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]     3         {Function} extern not_inlined 'main' -> 'int'
[003]     4           {Line}
[003]                 {Code} 'pushq   %rbp'
[003]                 {Code} 'movq    %rsp, %rbp'
[003]                 {Code} 'subq    $0x10, %rsp'
[003]                 {Code} 'movl    $0x0, -0x4(%rbp)'
[003]     5           {Line}
[003]                 {Code} 'movabsq $0x0, %rdi'
[003]                 {Code} 'movb    $0x0, %al'
[003]                 {Code} 'callq   0x0'
[003]     6           {Line}
[003]                 {Code} 'xorl    %eax, %eax'
[003]                 {Code} 'addq    $0x10, %rsp'
[003]                 {Code} 'popq    %rbp'
[003]                 {Code} 'retq'
[003]     6           {Line}

Logical View:
[000]           {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-64
[001]             {CompileUnit} 'hello-world.cpp'
[002]               {Producer} 'GNU C++14 9.3.0'
[002]     3         {Function} extern not_inlined 'main' -> 'int'
[003]     4           {Line}
[003]                 {Code} 'endbr64'
[003]                 {Code} 'pushq   %rbp'
[003]                 {Code} 'movq    %rsp, %rbp'
[003]     5           {Line}
[003]                 {Code} 'leaq    (%rip), %rdi'
[003]                 {Code} 'movl    $0x0, %eax'
[003]                 {Code} 'callq   0x0'
[003]     6           {Line}
[003]                 {Code} 'movl    $0x0, %eax'
[003]     7           {Line}
[003]                 {Code} 'popq    %rbp'
[003]                 {Code} 'retq'
[003]     7           {Line}

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

مثال زیر برای نشان دادن خروجی‌های متفاوتی که توسط llvm-debuginfo-analyzer تولید می‌شود، به کار رفته است. ما این مثال را برای مقصدهای X86 Codeview و ELF با نسخه‌های اخیر Clang، GCC و MSVC کامپایل کرده‌ایم (-O0 -g).

 1  int bar(float Input) { return (int)Input; }
 2 
 3  unsigned foo(char Param) {
 4    typedef int INT;                // ** Definition for INT **
 5    INT Value = Param;
 6    {
 7      typedef float FLOAT;          // ** Definition for FLOAT **
 8      {
 9        FLOAT Added = Value + Param;
10        Value = bar(Added);
11      }
12    }
13    return Value + Param;
14  }

آزمون بالا برای نشان دادن یک مشکل حوزهٔ دید (scope) که در کامپایلر Clang یافت شده استفاده می‌شود: PR44884 (Bugs LLVM) https://bugs.llvm.org/show_bug.cgi?id=44884 / PR44229 (GitHub LLVM) https://github.com/llvm/llvm-project/issues/44229

خط‌های ۴ و ۷ شامل ۲ دستور typedef هستند که در حوزه‌های واژگانی متفاوتی تعریف شده‌اند.

4    typedef int INT;
7      typedef float FLOAT;

این‌ها نماهای منطقی‌ای هستند که llvm-debuginfo-analyzer برای ۳ کامپایلر مختلف (MSVC، Clang و GCC) تولید می‌کند که قالب‌های مختلف اطلاعات اشکال‌زدایی (CodeView، DWARF) را در بسترهای گوناگون منتشر می‌کنند.

llvm-debuginfo-analyzer --attribute=level,format,producer
                        --print=symbols,types,lines
                        --output-sort=kind
                        pr-44884-codeview-clang.o
                        pr-44884-codeview-msvc.o
                        pr-44884-dwarf-clang.o
                        pr-44884-dwarf-gcc.o
Logical View:
[000]           {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64
[001]             {CompileUnit} 'pr-44884.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]               {Function} extern not_inlined 'bar' -> 'int'
[003]                 {Parameter} 'Input' -> 'float'
[003]     1           {Line}
[002]               {Function} extern not_inlined 'foo' -> 'unsigned'
[003]                 {Block}
[004]                   {Variable} 'Added' -> 'float'
[004]     9             {Line}
[004]    10             {Line}
[003]                 {Parameter} 'Param' -> 'char'
[003]                 {TypeAlias} 'FLOAT' -> 'float'
[003]                 {TypeAlias} 'INT' -> 'int'
[003]                 {Variable} 'Value' -> 'int'
[003]     3           {Line}
[003]     5           {Line}
[003]    13           {Line}

Logical View:
[000]           {File} 'pr-44884-codeview-msvc.o' -> COFF-i386
[001]             {CompileUnit} 'pr-44884.cpp'
[002]               {Producer} 'Microsoft (R) Optimizing Compiler'
[002]               {Function} extern not_inlined 'bar' -> 'int'
[003]                 {Variable} 'Input' -> 'float'
[003]     1           {Line}
[002]               {Function} extern not_inlined 'foo' -> 'unsigned'
[003]                 {Block}
[004]                   {Block}
[005]                     {Variable} 'Added' -> 'float'
[004]                   {TypeAlias} 'FLOAT' -> 'float'
[004]     9             {Line}
[004]    10             {Line}
[003]                 {TypeAlias} 'INT' -> 'int'
[003]                 {Variable} 'Param' -> 'char'
[003]                 {Variable} 'Value' -> 'int'
[003]     3           {Line}
[003]     5           {Line}
[003]    13           {Line}
[003]    14           {Line}

Logical View:
[000]           {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-44884.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]     1         {Function} extern not_inlined 'bar' -> 'int'
[003]     1           {Parameter} 'Input' -> 'float'
[003]     1           {Line}
[003]     1           {Line}
[003]     1           {Line}
[002]     3         {Function} extern not_inlined 'foo' -> 'unsigned int'
[003]                 {Block}
[004]     9             {Variable} 'Added' -> 'FLOAT'
[004]     9             {Line}
[004]     9             {Line}
[004]     9             {Line}
[004]     9             {Line}
[004]     9             {Line}
[004]    10             {Line}
[004]    10             {Line}
[004]    10             {Line}
[004]    13             {Line}
[003]     3           {Parameter} 'Param' -> 'char'
[003]     7           {TypeAlias} 'FLOAT' -> 'float'
[003]     4           {TypeAlias} 'INT' -> 'int'
[003]     5           {Variable} 'Value' -> 'INT'
[003]     3           {Line}
[003]     5           {Line}
[003]     5           {Line}
[003]    13           {Line}
[003]    13           {Line}
[003]    13           {Line}
[003]    13           {Line}
Logical View:
[000]           {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm
[001]             {CompileUnit} 'pr-44884.cpp'
[002]               {Producer} 'GNU C++14 10.2.1 20201103'
[002]     1         {Function} extern not_inlined 'bar' -> 'int'
[003]     1           {Parameter} 'Input' -> 'float'
[003]     1           {Line}
[003]     1           {Line}
[003]     1           {Line}
[002]     3         {Function} extern not_inlined 'foo' -> 'unsigned int'
[003]                 {Block}
[004]                   {Block}
[005]     9               {Variable} 'Added' -> 'FLOAT'
[005]     9               {Line}
[005]     9               {Line}
[005]     9               {Line}
[005]    10               {Line}
[005]    13               {Line}
[004]     7             {TypeAlias} 'FLOAT' -> 'float'
[003]     3           {Parameter} 'Param' -> 'char'
[003]     4           {TypeAlias} 'INT' -> 'int'
[003]     5           {Variable} 'Value' -> 'INT'
[003]     3           {Line}
[003]     5           {Line}
[003]    13           {Line}
[003]    14           {Line}
[003]    14           {Line}

از نماهای منطقی پیشین، می‌توان دریافت که کامپایلر Clang هر دو typedef را در یک حوزه لغوی یکسان (3) تولید می‌کند، که نادرست است. کامپایلرهای GCC و MSVC حوزه لغوی صحیحی را برای هر دو typedef صادر می‌کنند.

با استفاده از امکانات گزینش llvm-debuginfo-analyzer، می‌توانیم یک خروجی جدولی ساده ایجاد کنیم که فقط انواع منطقی را که Typedef هستند نشان دهد.

llvm-debuginfo-analyzer --attribute=level,format
                        --output-sort=name
                        --select-types=Typedef
                        --report=list
                        --print=types
                        pr-44884-*.o
Logical View:
[000]           {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64
[001]           {CompileUnit} 'pr_44884.cpp'
[003]           {TypeAlias} 'FLOAT' -> 'float'
[003]           {TypeAlias} 'INT' -> 'int'
Logical View:
[000]           {File} 'pr-44884-codeview-msvc.o' -> COFF-i386
[001]           {CompileUnit} 'pr_44884.cpp'
[004]           {TypeAlias} 'FLOAT' -> 'float'
[003]           {TypeAlias} 'INT' -> 'int'
Logical View:
[000]           {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64
[001]           {CompileUnit} 'pr_44884.cpp'
[003]     7     {TypeAlias} 'FLOAT' -> 'float'
[003]     4     {TypeAlias} 'INT' -> 'int'
Logical View:
[000]           {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm
[001]           {CompileUnit} 'pr_44884.cpp'
[004]     7     {TypeAlias} 'FLOAT' -> 'float'
[003]     4     {TypeAlias} 'INT' -> 'int'

این امر همچنین نشان می‌دهد که اطلاعات اشکال‌زدایی CodeView شماره خطوط کد منبع را برای این انواع منطقی تولید نمی‌کند. نمای منطقی بر اساس نام انواع مرتب شده است..SS مورد آزمون ۴ - شمارش‌های تودرتوی مفقود (TEST CASE 4 - MISSING NESTED ENUMERATIONS)

مثال زیر برای نشان دادن خروجی‌های متفاوتی که توسط llvm-debuginfo-analyzer تولید می‌شود به کار رفته است. ما این مثال را برای مقصدهای X86 Codeview و ELF با نگارش‌های اخیر Clang، GCC و MSVC کامپایل کردیم (-O0 -g).

 1  struct Struct {
 2    union Union {
 3      enum NestedEnum { RED, BLUE };
 4    };
 5    Union U;
 6  };
 7
 8  Struct S;
 9  int test() {
10    return S.U.BLUE;
11  }

آزمون بالا برای نشان دادن یک مشکل حوزه (scope issue) یافت‌شده در کامپایلر Clang استفاده می‌شود: PR46466 (Bugs LLVM) https://bugs.llvm.org/show_bug.cgi?id=46466 / PR45811 (GitHub LLVM) https://github.com/llvm/llvm-project/issues/45811

این‌ها نماهای منطقی هستند که llvm-debuginfo-analyzer برای ۳ کامپایلر مختلف (MSVC، Clang و GCC) تولید می‌کند که قالب‌های متفاوتی از اطلاعات اشکال‌زدایی (CodeView، DWARF) را روی بسترهای مختلف منتشر می‌سازند.

llvm-debuginfo-analyzer --attribute=level,format,producer
                        --output-sort=name
                        --print=symbols,types
                        pr-46466-codeview-clang.o
                        pr-46466-codeview-msvc.o
                        pr-46466-dwarf-clang.o
                        pr-46466-dwarf-gcc.o

Logical View:
[000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
[001]             {CompileUnit} 'pr-46466.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]               {Variable} extern 'S' -> 'Struct'
[002]     1         {Struct} 'Struct'
[003]                 {Member} public 'U' -> 'Union'
[003]     2           {Union} 'Union'
[004]     3             {Enumeration} 'NestedEnum' -> 'int'
[005]                     {Enumerator} 'BLUE' = '0x1'
[005]                     {Enumerator} 'RED' = '0x0'

Logical View:
[000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
[001]             {CompileUnit} 'pr-46466.cpp'
[002]               {Producer} 'Microsoft (R) Optimizing Compiler'
[002]               {Variable} extern 'S' -> 'Struct'
[002]     1         {Struct} 'Struct'
[003]                 {Member} public 'U' -> 'Union'
[003]     2           {Union} 'Union'
[004]     3             {Enumeration} 'NestedEnum' -> 'int'
[005]                     {Enumerator} 'BLUE' = '0x1'
[005]                     {Enumerator} 'RED' = '0x0'
Logical View:
[000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-46466.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]     8         {Variable} extern 'S' -> 'Struct'
[002]     1         {Struct} 'Struct'
[003]     5           {Member} public 'U' -> 'Union'

Logical View:
[000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-46466.cpp'
[002]               {Producer} 'GNU C++14 9.3.0'
[002]     8         {Variable} extern 'S' -> 'Struct'
[002]     1         {Struct} 'Struct'
[003]     5           {Member} public 'U' -> 'Union'
[003]     2           {Union} 'Union'
[004]     3             {Enumeration} 'NestedEnum' -> 'unsigned int'
[005]                     {Enumerator} 'BLUE' = '0x1'
[005]                     {Enumerator} 'RED' = '0x0'

از نماهای منطقی پیشین، می‌توان دریافت که اطلاعات اشکال‌زدایی DWARF تولیدشده توسط کامپایلر Clang شامل هیچ ارجاعی به شمارنده‌های RED و BLUE نیست. در حالی که DWARF تولیدشده توسط GCC، و CodeView تولیدشده توسط Clang و MSVC، حاوی چنین ارجاعاتی هستند.

با استفاده از امکانات گزینش llvm-debuginfo-analyzer، می‌توانیم یک نمای منطقی تولید کنیم که تنها نوع‌های منطقیِ Enumerator و والدین آن‌ها را نشان دهد. این نمای منطقی بر اساس نام نوع‌ها مرتب شده است.

llvm-debuginfo-analyzer --attribute=format,level
                        --output-sort=name
                        --select-types=Enumerator
                        --report=parents
                        --print=types
                        pr-46466-*.o
Logical View:
[000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
[001]             {CompileUnit} 'pr-46466.cpp'
[002]     1         {Struct} 'Struct'
[003]     2           {Union} 'Union'
[004]     3             {Enumeration} 'NestedEnum' -> 'int'
[005]                     {Enumerator} 'BLUE' = '0x1'
[005]                     {Enumerator} 'RED' = '0x0'
Logical View:
[000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
[001]             {CompileUnit} 'pr-46466.cpp'
[002]     1         {Struct} 'Struct'
[003]     2           {Union} 'Union'
[004]     3             {Enumeration} 'NestedEnum' -> 'int'
[005]                     {Enumerator} 'BLUE' = '0x1'
[005]                     {Enumerator} 'RED' = '0x0'
Logical View:
[000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-46466.cpp'
Logical View:
[000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-46466.cpp'
[002]     1         {Struct} 'Struct'
[003]     2           {Union} 'Union'
[004]     3             {Enumeration} 'NestedEnum' -> 'unsigned int'
[005]                     {Enumerator} 'BLUE' = '0x1'
[005]                     {Enumerator} 'RED' = '0x0'

با استفاده از امکانات گزینش llvm-debuginfo-analyzer، می‌توانیم یک خروجی جدولی ساده شامل خلاصه‌ای از نوع‌های منطقی که Enumerator هستند تولید کنیم. این نمای منطقی بر اساس نام نوع‌ها مرتب شده است.

llvm-debuginfo-analyzer --attribute=format,level
                        --output-sort=name
                        --select-types=Enumerator
                        --print=types,summary
                        pr-46466-*.o
Logical View:
[000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
[001]           {CompileUnit} 'pr-46466.cpp'
[005]           {Enumerator} 'BLUE' = '0x1'
[005]           {Enumerator} 'RED' = '0x0'
-----------------------------
Element      Total      Found
-----------------------------
Scopes           5          0
Symbols          2          0
Types            6          2
Lines            0          0
-----------------------------
Total           13          2
Logical View:
[000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
[001]           {CompileUnit} 'pr-46466.cpp'
[005]           {Enumerator} 'BLUE' = '0x1'
[005]           {Enumerator} 'RED' = '0x0'
-----------------------------
Element      Total      Found
-----------------------------
Scopes           5          0
Symbols          2          0
Types            7          2
Lines            0          0
-----------------------------
Total           14          2
Logical View:
[000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
[001]           {CompileUnit} 'pr-46466.cpp'
-----------------------------
Element      Total      Found
-----------------------------
Scopes           4          0
Symbols          0          0
Types            0          0
Lines            0          0
-----------------------------
Total            4          0
Logical View:
[000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
[001]           {CompileUnit} 'pr-46466.cpp'
[005]           {Enumerator} 'BLUE' = '0x1'
[005]           {Enumerator} 'RED' = '0x0'
-----------------------------
Element      Total      Found
-----------------------------
Scopes           5          0
Symbols          0          0
Types            2          2
Lines            0          0
-----------------------------
Total            7          2
از مقادیر چاپ‌شده در ستون Found، می‌توان دید که هیچ Types در اطلاعات اشکال‌زدایی DWARF تولیدشده توسط Clang یافت نشد.

مثال زیر برای نشان دادن خروجی‌های متفاوتی که توسط llvm-debuginfo-analyzer تولید می‌شود به کار می‌رود. ما مثال را برای هدف‌های X86 Codeview و ELF با نسخه‌های اخیر Clang، GCC و MSVC کامپایل کردیم (-O0 -g).

// definitions.h
#ifdef _MSC_VER
  #define forceinline __forceinline
#elif defined(__clang__)
  #if __has_attribute(__always_inline__)
    #define forceinline inline __attribute__((__always_inline__))
  #else
    #define forceinline inline
  #endif
#elif defined(__GNUC__)
  #define forceinline inline __attribute__((__always_inline__))
#else
  #define forceinline inline
  #error
#endif

از آنجا که آزمون به گزینه‌های inline کامپایلر وابسته است، فایل سربرگ فوق forceinline را تعریف می‌کند.

#include "definitions.h"
 1  #include "definitions.h"
 2  forceinline int InlineFunction(int Param) {
 3    int Var_1 = Param;
 4    {
 5      int Var_2 = Param + Var_1;
 6      Var_1 = Var_2;
 7    }
 8    return Var_1;
 9  }
10
11  int test(int Param_1, int Param_2) {
12    int A = Param_1;
13    A += InlineFunction(Param_2);
14    return A;
15  }

آزمون بالا برای تشریح مشکل متغیری که در کامپایلر Clang یافت شده استفاده می‌شود: PR43860 (Bugs LLVM) https://bugs.llvm.org/show_bug.cgi?id=43860 / PR43205 (GitHub) https://github.com/llvm/llvm-project/issues/43205

این‌ها نماهای منطقی هستند که llvm-debuginfo-analyzer برای ۳ کامپایلر مختلف (MSVC، Clang و GCC) تولید می‌کند که قالب‌های گوناگون اطلاعات اشکال‌زدایی (CodeView، DWARF) را در بسترهای مختلف منتشر می‌کنند.

llvm-debuginfo-analyzer --attribute=level,format,producer
                        --output-sort=name
                        --print=symbols
                        pr-43860-codeview-clang.o
                        pr-43860-codeview-msvc.o
                        pr-43860-dwarf-clang.o
                        pr-43860-dwarf-gcc.o
Logical View:
[000]           {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64
[001]             {CompileUnit} 'pr-43860.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]     2         {Function} inlined 'InlineFunction' -> 'int'
[003]                 {Parameter} '' -> 'int'
[002]               {Function} extern not_inlined 'test' -> 'int'
[003]                 {Variable} 'A' -> 'int'
[003]                 {InlinedFunction} inlined 'InlineFunction' -> 'int'
[004]                   {Parameter} 'Param' -> 'int'
[004]                   {Variable} 'Var_1' -> 'int'
[004]                   {Variable} 'Var_2' -> 'int'
[003]                 {Parameter} 'Param_1' -> 'int'
[003]                 {Parameter} 'Param_2' -> 'int'

Logical View:
[000]           {File} 'pr-43860-codeview-msvc.o' -> COFF-i386
[001]             {CompileUnit} 'pr-43860.cpp'
[002]               {Producer} 'Microsoft (R) Optimizing Compiler'
[002]               {Function} extern not_inlined 'InlineFunction' -> 'int'
[003]                 {Block}
[004]                   {Variable} 'Var_2' -> 'int'
[003]                 {Variable} 'Param' -> 'int'
[003]                 {Variable} 'Var_1' -> 'int'
[002]               {Function} extern not_inlined 'test' -> 'int'
[003]                 {Variable} 'A' -> 'int'
[003]                 {Variable} 'Param_1' -> 'int'
[003]                 {Variable} 'Param_2' -> 'int'

Logical View:
[000]           {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-43860.cpp'
[002]               {Producer} 'clang version 14.0.0'
[002]     2         {Function} extern inlined 'InlineFunction' -> 'int'
[003]                 {Block}
[004]     5             {Variable} 'Var_2' -> 'int'
[003]     2           {Parameter} 'Param' -> 'int'
[003]     3           {Variable} 'Var_1' -> 'int'
[002]    11         {Function} extern not_inlined 'test' -> 'int'
[003]    12           {Variable} 'A' -> 'int'
[003]    13           {InlinedFunction} inlined 'InlineFunction' -> 'int'
[004]                   {Block}
[005]                     {Variable} 'Var_2' -> 'int'
[004]                   {Parameter} 'Param' -> 'int'
[004]                   {Variable} 'Var_1' -> 'int'
[003]    11           {Parameter} 'Param_1' -> 'int'
[003]    11           {Parameter} 'Param_2' -> 'int'

Logical View:
[000]           {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64
[001]             {CompileUnit} 'pr-43860.cpp'
[002]               {Producer} 'GNU C++14 9.3.0'
[002]     2         {Function} extern declared_inlined 'InlineFunction' -> 'int'
[003]                 {Block}
[004]     5             {Variable} 'Var_2' -> 'int'
[003]     2           {Parameter} 'Param' -> 'int'
[003]     3           {Variable} 'Var_1' -> 'int'
[002]    11         {Function} extern not_inlined 'test' -> 'int'
[003]    12           {Variable} 'A' -> 'int'
[003]    13           {InlinedFunction} declared_inlined 'InlineFunction' -> 'int'
[004]                   {Block}
[005]                     {Variable} 'Var_2' -> 'int'
[004]                   {Parameter} 'Param' -> 'int'
[004]                   {Variable} 'Var_1' -> 'int'
[003]    11           {Parameter} 'Param_1' -> 'int'
[003]    11           {Parameter} 'Param_2' -> 'int'

از نماهای منطقی پیشین، می‌توان مشاهده کرد که اطلاعات اشکال‌زدایی CodeView تولیدشده توسط کامپایلر Clang نشان می‌دهد متغیرهای Var_1 و Var_2 در تابع InlineFuction در یک حوزهٔ واژگانی یکسان (4) قرار دارند. DWARF تولیدشده توسط GCC/Clang و CodeView تولیدشده توسط MSVC، این متغیرها را در حوزهٔ واژگانی درست نشان می‌دهند: به‌ترتیب 3 و 4.

با استفاده از امکانات گزینش llvm-debuginfo-analyzer، می‌توانیم یک خروجی جدولی ساده تولید کنیم که تنها عناصر منطقی دارای الگوی var در نامشان را نشان می‌دهد. نمای منطقی بر اساس نام متغیرها مرتب شده است.

llvm-debuginfo-analyzer --attribute=level,format
                        --output-sort=name
                        --select-regex --select-nocase --select=Var
                        --report=list
                        --print=symbols
                        pr-43860-*.o
Logical View:
[000]           {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64
[001]           {CompileUnit} 'pr-43860.cpp'
[004]           {Variable} 'Var_1' -> 'int'
[004]           {Variable} 'Var_2' -> 'int'
Logical View:
[000]           {File} 'pr-43860-codeview-msvc.o' -> COFF-i386
[001]           {CompileUnit} 'pr-43860.cpp'
[003]           {Variable} 'Var_1' -> 'int'
[004]           {Variable} 'Var_2' -> 'int'
Logical View:
[000]           {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64
[001]           {CompileUnit} 'pr-43860.cpp'
[004]           {Variable} 'Var_1' -> 'int'
[003]     3     {Variable} 'Var_1' -> 'int'
[005]           {Variable} 'Var_2' -> 'int'
[004]     5     {Variable} 'Var_2' -> 'int'
Logical View:
[000]           {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64
[001]           {CompileUnit} 'pr-43860.cpp'
[004]           {Variable} 'Var_1' -> 'int'
[003]     3     {Variable} 'Var_1' -> 'int'
[005]           {Variable} 'Var_2' -> 'int'
[004]     5     {Variable} 'Var_2' -> 'int'

همچنین نشان می‌دهد که اطلاعات اشکال‌زدایی CodeView شماره خطوط کد منبع را برای آن نمادهای منطقی تولید نمی‌کند. نمای منطقی بر اساس نام نوع‌ها مرتب شده است..SS "مورد آزمایشی ۶ - نمای منطقی کامل (TEST CASE 6 - FULL LOGICAL VIEW)"

برای کاربران پیشرفته، llvm-debuginfo-analyzer می‌تواند اطلاعات سطح پایینی را نمایش دهد که شامل آفست‌ها درون بخش اطلاعات اشکال‌زدایی، عملوندهای مکان اشکال‌زدایی، نام‌های پیوند و غیره است.

llvm-debuginfo-analyzer --attribute=all
                        --print=all
                        test-dwarf-clang.o
Logical View:
[0x0000000000][000]            {File} 'test-dwarf-clang.o' -> elf64-x86-64
[0x000000000b][001]              {CompileUnit} 'test.cpp'
[0x000000000b][002]                {Producer} 'clang version 12.0.0'
                                   {Directory} ''
                                   {File} 'test.cpp'
                                   {Public} 'foo' [0x0000000000:0x000000003a]
[0x000000000b][002]                {Range} Lines 2:9 [0x0000000000:0x000000003a]
[0x00000000bc][002]                {BaseType} 'bool'
[0x0000000099][002]                {BaseType} 'int'
[0x00000000b5][002]                {BaseType} 'unsigned int'
[0x00000000a0][002]   {Source} '/test.cpp'
[0x00000000a0][002]      1         {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
[0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
[0x000000002a][003]                  {Range} Lines 2:9 [0x0000000000:0x000000003a]
[0x000000002a][003]                  {Linkage}  0x2 '_Z3fooPKijb'
[0x0000000071][003]                  {Block}
[0x0000000071][004]                    {Range} Lines 5:8 [0x000000001c:0x000000002f]
[0x000000007e][004]      5             {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
[0x000000007e][005]                      {Coverage} 100.00%
[0x000000007f][005]                      {Location}
[0x000000007f][006]                        {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
[0x000000001c][004]      5             {Line} {NewStatement} '/test.cpp'
[0x000000001c][004]                    {Code} 'movl   $0x7, -0x1c(%rbp)'
[0x0000000023][004]      6             {Line} {NewStatement} '/test.cpp'
[0x0000000023][004]                    {Code} 'movl   $0x7, -0x4(%rbp)'
[0x000000002a][004]                    {Code} 'jmp    0x6'
[0x000000002f][004]      8             {Line} {NewStatement} '/test.cpp'
[0x000000002f][004]                    {Code} 'movl   -0x14(%rbp), %eax'
[0x0000000063][003]      2           {Parameter} 'ParamBool' -> [0x00000000bc]'bool'
[0x0000000063][004]                    {Coverage} 100.00%
[0x0000000064][004]                    {Location}
[0x0000000064][005]                      {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg]
[0x0000000047][003]      2           {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR'
[0x0000000047][004]                    {Coverage} 100.00%
[0x0000000048][004]                    {Location}
[0x0000000048][005]                      {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg]
[0x0000000055][003]      2           {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int'
[0x0000000055][004]                    {Coverage} 100.00%
[0x0000000056][004]                    {Location}
[0x0000000056][005]                      {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg]
[0x000000008d][003]      4           {TypeAlias} 'INTEGER' -> [0x0000000099]'int'
[0x0000000000][003]      2           {Line} {NewStatement} '/test.cpp'
[0x0000000000][003]                  {Code} 'pushq    %rbp'
[0x0000000001][003]                  {Code} 'movq     %rsp, %rbp'
[0x0000000004][003]                  {Code} 'movb     %dl, %al'
[0x0000000006][003]                  {Code} 'movq     %rdi, -0x10(%rbp)'
[0x000000000a][003]                  {Code} 'movl     %esi, -0x14(%rbp)'
[0x000000000d][003]                  {Code} 'andb     $0x1, %al'
[0x000000000f][003]                  {Code} 'movb     %al, -0x15(%rbp)'
[0x0000000012][003]      3           {Line} {NewStatement} {PrologueEnd} '/test.cpp'
[0x0000000012][003]                  {Code} 'testb    $0x1, -0x15(%rbp)'
[0x0000000016][003]                  {Code} 'je       0x13'
[0x0000000032][003]      8           {Line} '/test.cpp'
[0x0000000032][003]                  {Code} 'movl     %eax, -0x4(%rbp)'
[0x0000000035][003]      9           {Line} {NewStatement} '/test.cpp'
[0x0000000035][003]                  {Code} 'movl     -0x4(%rbp), %eax'
[0x0000000038][003]                  {Code} 'popq     %rbp'
[0x0000000039][003]                  {Code} 'retq'
[0x000000003a][003]      9           {Line} {NewStatement} {EndSequence} '/test.cpp'
-----------------------------
Element      Total    Printed
-----------------------------
Scopes           3          3
Symbols          4          4
Types            5          5
Lines           25         25
-----------------------------
Total           37         37
Scope Sizes:
       189 (100.00%) : [0x000000000b][001]              {CompileUnit} 'test.cpp'
       110 ( 58.20%) : [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
        27 ( 14.29%) : [0x0000000071][003]                  {Block}
Totals by lexical level:
[001]:        189 (100.00%)
[002]:        110 ( 58.20%)
[003]:         27 ( 14.29%)

جدول Scope Sizes سهم هر حوزه را بر حسب بایت در اطلاعات اشکال‌زدایی نشان می‌دهد، که می‌توان از آن برای تشخیص تغییرات اندازهٔ غیرمنتظره در بخش‌های DWARF بین نسخه‌های مختلف یک زنجیره ابزار استفاده کرد.

[0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
[0x000000002a][003]                  {Range} Lines 2:9 [0x0000000000:0x000000003a]
[0x000000002a][003]                  {Linkage}  0x2 '_Z3fooPKijb'
[0x0000000071][003]                  {Block}
[0x0000000071][004]                    {Range} Lines 5:8 [0x000000001c:0x000000002f]
[0x000000007e][004]      5             {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
[0x000000007e][005]                      {Coverage} 100.00%
[0x000000007f][005]                      {Location}
[0x000000007f][006]                        {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]

صفت {Range} محدوده‌های خط را برای یک حوزهٔ منطقی توصیف می‌کند. در این مورد، تابع foo بین خطوط 2 و 9 قرار دارد.

صفت‌های {Coverage} و {Location} مکان و پوشش اشکال‌زدایی را برای نمادهای منطقی توصیف می‌کنند. برای کدهای بهینه‌سازی‌شده، مقدار پوشش کاهش می‌یابد و این امر بر قابلیت اشکال‌زدایی برنامه اثر می‌گذارد..SS "پشتیبانی از وب‌اسمبلی (WEBASSEMBLY SUPPORT)"

مثال زیر برای نشان دادن خروجی WebAssembly تولیدشده توسط llvm-debuginfo-analyzer به کار می‌رود. ما این مثال را برای یک مقصد ۳۲-بیتی WebAssembly با Clang (-O0 -g --target=wasm32) کامپایل کردیم:

1  using INTPTR = const int *;
2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
3    if (ParamBool) {
4      typedef int INTEGER;
5      const INTEGER CONSTANT = 7;
6      return CONSTANT;
7    }
8    return ParamUnsigned;
9  }

دستور زیر جزئیات پایه را برای تمام عنصرهای منطقی مرتب‌شده بر اساس آفست درونی اطلاعات اشکال‌زدایی چاپ می‌کند؛ این شامل سطح لغوی و قالب اطلاعات اشکال‌زدایی آن است.

llvm-debuginfo-analyzer --attribute=level,format
                        --output-sort=offset
                        --print=scopes,symbols,types,lines,instructions
                        test-clang.o

یا

llvm-debuginfo-analyzer --attribute=level,format
                        --output-sort=offset
                        --print=elements
                        test-clang.o

هر سطر نشان‌دهنده عنصری است که درون اطلاعات اشکال‌زدایی وجود دارد. ستون نخست بیانگر سطح حوزه، سپس شماره خط مربوطه (در صورت وجود) و در نهایت شرح آن عنصر است.

Logical View:
[000]           {File} 'test-clang.o' -> WASM
[001]             {CompileUnit} 'test.cpp'
[002]     2         {Function} extern not_inlined 'foo' -> 'int'
[003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
[003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
[003]     2           {Parameter} 'ParamBool' -> 'bool'
[003]                 {Block}
[004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
[004]     5             {Line}
[004]                   {Code} 'i32.const     7'
[004]                   {Code} 'local.set     10'
[004]                   {Code} 'local.get     5'
[004]                   {Code} 'local.get     10'
[004]                   {Code} 'i32.store     12'
[004]     6             {Line}
[004]                   {Code} 'i32.const     7'
[004]                   {Code} 'local.set     11'
[004]                   {Code} 'local.get     5'
[004]                   {Code} 'local.get     11'
[004]                   {Code} 'i32.store     28'
[004]                   {Code} 'br            1'
[004]     -             {Line}
[004]                   {Code} 'end'
[003]     4           {TypeAlias} 'INTEGER' -> 'int'
[003]     2           {Line}
[003]                 {Code} 'nop'
[003]                 {Code} 'end'
[003]                 {Code} 'i64.div_s'
[003]                 {Code} 'global.get      0'
[003]                 {Code} 'local.set       3'
[003]                 {Code} 'i32.const       32'
[003]                 {Code} 'local.set       4'
[003]                 {Code} 'local.get       3'
[003]                 {Code} 'local.get       4'
[003]                 {Code} 'i32.sub'
[003]                 {Code} 'local.set       5'
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'local.get       0'
[003]                 {Code} 'i32.store       24'
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'local.get       1'
[003]                 {Code} 'i32.store       20'
[003]                 {Code} 'local.get       2'
[003]                 {Code} 'local.set       6'
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'local.get       6'
[003]                 {Code} 'i32.store8      19'
[003]     3           {Line}
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'i32.load8_u     19'
[003]                 {Code} 'local.set       7'
[003]     3           {Line}
[003]                 {Code} 'i32.const       1'
[003]                 {Code} 'local.set       8'
[003]                 {Code} 'local.get       7'
[003]                 {Code} 'local.get       8'
[003]                 {Code} 'i32.and'
[003]                 {Code} 'local.set       9'
[003]                 {Code} 'block'
[003]                 {Code} 'block'
[003]                 {Code} 'local.get       9'
[003]                 {Code} 'i32.eqz'
[003]                 {Code} 'br_if           0'
[003]     8           {Line}
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'i32.load        20'
[003]                 {Code} 'local.set       12'
[003]     8           {Line}
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'local.get       12'
[003]                 {Code} 'i32.store       28'
[003]     -           {Line}
[003]                 {Code} 'end'
[003]     9           {Line}
[003]                 {Code} 'local.get       5'
[003]                 {Code} 'i32.load        28'
[003]                 {Code} 'local.set       13'
[003]                 {Code} 'local.get       13'
[003]                 {Code} 'return'
[003]                 {Code} 'end'
[003]     9           {Line}
[003]                 {Code} 'unreachable'
[002]     1         {TypeAlias} 'INTPTR' -> '* const int'

دستور زیر تمام instructions، symbols و types را که در نام یا نوع خود حاوی 'block' یا '.store' هستند، با استفاده از یک چیدمان تب‌بندی‌شده و با ارائه تعداد موارد منطبق چاپ می‌کند.

llvm-debuginfo-analyzer --attribute=level
                        --select-nocase --select-regex
                        --select=BLOCK --select=.store
                        --report=list
                        --print=symbols,types,instructions,summary
                        test-clang.o
Logical View:
[000]           {File} 'test-clang.o'
[001]           {CompileUnit} 'test.cpp'
[003]           {Code} 'block'
[003]           {Code} 'block'
[004]           {Code} 'i32.store     12'
[003]           {Code} 'i32.store     20'
[003]           {Code} 'i32.store     24'
[004]           {Code} 'i32.store     28'
[003]           {Code} 'i32.store     28'
[003]           {Code} 'i32.store8    19'
-----------------------------
Element      Total    Printed
-----------------------------
Scopes           3          0
Symbols          4          0
Types            2          0
Lines           62          8
-----------------------------
Total           71          8

با توجه به مثال قبلی، با مقایسه در برابر یک کامپایلر دیگر، اشکال فوق در اطلاعات اشکال‌زدایی (مربوط به مکان نامعتبر پیشین حوزه برای 'typedef int INTEGER') را پیدا کردیم.

با استفاده از GCC برای تولید test-dwarf-gcc.o، می‌توانیم یک الگوی انتخاب را به همراه حالت چاپ اعمال کنیم تا خروجی نمای منطقی زیر به دست آید.

llvm-debuginfo-analyzer --attribute=level
                        --select-regex --select-nocase --select=INTe
                        --report=list
                        --print=symbols,types
                        test-clang.o test-dwarf-gcc.o
Logical View:
[000]           {File} 'test-clang.o'
[001]           {CompileUnit} 'test.cpp'
[003]     4     {TypeAlias} 'INTEGER' -> 'int'
[004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
Logical View:
[000]           {File} 'test-dwarf-gcc.o'
[001]           {CompileUnit} 'test.cpp'
[004]     4     {TypeAlias} 'INTEGER' -> 'int'
[004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'

خروجی نشان می‌دهد که هر دو شیء حاوی عناصر یکسانی هستند؛ اما 'typedef INTEGER' در سطح حوزه (scope level) متفاوتی قرار گرفته است. شیء تولیدشده توسط GCC مقدار '4' را نشان می‌دهد که مقدار صحیح است.

دو روش مقایسه وجود دارد: نمای منطقی و عناصر منطقی..SS "نمای منطقی (LOGICAL VIEW)"

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

خروجی، عناصر ازدست‌رفته (-) و اضافه‌شده (+) را در قالب نما نشان می‌دهد و با جابه‌جا کردن فایل‌های شیء مرجع و هدف، زمینه و اطلاعات بیشتری ارائه می‌دهد.

llvm-debuginfo-analyzer --attribute=level
                        --compare=types
                        --report=view
                        --print=symbols,types
                        test-clang.o test-dwarf-gcc.o
Reference: 'test-clang.o'
Target:    'test-dwarf-gcc.o'
Logical View:
 [000]           {File} 'test-clang.o'
 [001]             {CompileUnit} 'test.cpp'
 [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 [002]     2         {Function} extern not_inlined 'foo' -> 'int'
 [003]                 {Block}
 [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
+[004]     4             {TypeAlias} 'INTEGER' -> 'int'
 [003]     2           {Parameter} 'ParamBool' -> 'bool'
 [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
 [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
-[003]     4           {TypeAlias} 'INTEGER' -> 'int'

خروجی، مسیر ادغام نما (مرجع و هدف) را همراه با عناصر ازدست‌رفته و اضافه‌شده نشان می‌دهد.

این حالت، عناصر منطقی منفرد را بدون در نظر گرفتن یکسان بودن والدین آن‌ها مقایسه می‌کند. در هر دو روش مقایسه، معیارهای برابری شامل نام، مکان در کد منبع، نوع و سطح حوزهٔ لغوی (lexical scope level) است.

llvm-debuginfo-analyzer --attribute=level
                        --compare=types
                        --report=list
                        --print=symbols,types,summary
                        test-clang.o test-dwarf-gcc.o
Reference: 'test-clang.o'
Target:    'test-dwarf-gcc.o'
(1) Missing Types:
-[003]     4     {TypeAlias} 'INTEGER' -> 'int'
(1) Added Types:
+[004]     4     {TypeAlias} 'INTEGER' -> 'int'
----------------------------------------
Element   Expected    Missing      Added
----------------------------------------
Scopes           4          0          0
Symbols          0          0          0
Types            2          1          1
Lines            0          0          0
----------------------------------------
Total            6          1          1

تغییر ترتیب Reference و Target:

llvm-debuginfo-analyzer --attribute=level
                        --compare=types
                        --report=list
                        --print=symbols,types,summary
                        test-dwarf-gcc.o test-clang.o
Reference: 'test-dwarf-gcc.o'
Target:    'test-clang.o'
(1) Missing Types:
-[004]     4     {TypeAlias} 'INTEGER' -> 'int'
(1) Added Types:
+[003]     4     {TypeAlias} 'INTEGER' -> 'int'
----------------------------------------
Element   Expected    Missing      Added
----------------------------------------
Scopes           4          0          0
Symbols          0          0          0
Types            2          1          1
Lines            0          0          0
----------------------------------------
Total            6          1          1

با توجه به جابه‌جا شدن Reference و Target، موارد Added Types در حالت اول، اکنون به‌عنوان Missing Types فهرست می‌شوند..SH "وضعیت خروج (EXIT STATUS)"

در صورتی که فایل‌های ورودی با موفقیت تجزیه و چاپ شوند، llvm-debuginfo-analyzer مقدار 0 را برمی‌گرداند. در غیر این صورت، مقدار 1 را بازمی‌گرداند.

به Limitations مراجعه کنید.

llvm-dwarfdump <llvm-dwarfdump.html>

توسط تیم LLVM نگهداری می‌شود (https://llvm.org).

2003-2026, LLVM Project

2026-07-15 22