ABICOMPAT(1) Libabigail ABICOMPAT(1)

abicompat - بررسی سازگاری ABI

دستور abicompat بررسی می‌کند که آیا برنامه‌ای که با یک کتابخانه مشترک مشخص پیوند خورده است، همچنان با نسخه‌های بعدی آن کتابخانه از نظر ABI سازگار است یا خیر. اگر نسخه جدید کتابخانه ناسازگاری ABI ایجاد کند، abicompat کاربر را راهنمایی کرده و دقیقاً مشخص می‌کند که آن ناسازگاری چیست.

abicompat [options] [<application> <shared-library-first-version> <shared-library-second-version>]

  • --help

    نمایش راهنمای کوتاهی درباره دستور و خروج.

  • --version | -v

    نمایش نسخه برنامه و خروج.

  • --list-undefined-symbols | -u

    نمایش فهرست نمادهای تعریف‌نشده (undefined symbols) برنامه و خروج.

  • --show-base-names | -b

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

  • --app-debug-info-dir | --appd <path-to-app-debug-info-directory>

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

  • --lib-debug-info-dir1 | --libd1 <path-to-lib1-debug-info>

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

  • --lib-debug-info-dir2 | --libd2 <path-to-lib1-debug-info>

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

  • --suppressions | --suppr <path-to-suppressions>

    استفاده از یک فایل مشخصات نادیده‌گیری (suppression specification) <#suppr-spec-label> واقع در path-to-suppressions. توجه داشته باشید که این گزینه می‌تواند چندین بار در خط فرمان تکرار شود؛ در این صورت تمامی فایل‌های مشخصات نادیده‌گیری اعمال خواهند شد.

  • --no-show-locs
اطلاعات مربوط به محل تغییر نوع مربوطه در کتابخانه مشترک دوم نمایش داده نشود.
  • --btf

    هنگام مقایسه باینری‌ها، اطلاعات ABI را در صورت وجود از اطلاعات اشکال‌زدایی BTF استخراج کن.

  • --ctf

    هنگام مقایسه باینری‌ها، اطلاعات ABI را در صورت وجود از اطلاعات اشکال‌زدایی CTF استخراج کن.

  • --fail-no-debug-info

    اگر هیچ اطلاعات اشکال‌زدایی یافت نشد، این گزینه باعث شکست اجرای برنامه می‌شود. در غیر این صورت و بدون این گزینه، برنامه تلاش می‌کند ویژگی‌هایی از باینری‌ها را که وابسته به اطلاعات اشکال‌زدایی نیستند (مانند مشخصات صرفاً ELF) مقایسه کند.

  • --ignore-soname

    نادیده گرفتن تفاوت‌های SONAME هنگام انجام مقایسه.

  • --weak-mode

    این گزینه حالت ضعیف (weak mode) ابزار abicompat را فعال می‌کند. در این حالت، تنها به یک نسخه از کتابخانه نیاز است. به این صورت که abicompat به شکل زیر فراخوانی می‌شود:

abicompat --weak-mode <the-application> <the-library>

توجه داشته باشید که اگر همراه با برنامه تنها یک نسخه از کتابخانه ارائه شود، حتی می‌توان از گزینه --weak-mode نیز صرف‌نظر کرد؛ در این حالت، abicompat به طور خودکار به حالت ضعیف تغییر وضعیت می‌دهد:

abicompat <the-application> <the-library>

در این حالت ضعیف، نوع توابع و متغیرهایی که توسط کتابخانه صادر (export) شده و توسط برنامه مصرف می‌شوند (بدین معنی که نمادهای این توابع و متغیرها در برنامه تعریف‌نشده هستند و در کتابخانه تعریف و صادر شده‌اند)، با نسخه‌ای از این نوع‌ها که برنامه انتظار دارد مقایسه می‌شوند. و اگر این دو نسخه از نوع‌ها متفاوت باشند، abicompat تفاوت‌ها را به کاربر نشان می‌دهد.

به عبارت دیگر، در این حالت، abicompat بررسی می‌کند که تا جایی که به ABI مربوط است، انواع توابع و متغیرهای صادرشده توسط کتابخانه همان معنایی را داشته باشند که برنامه انتظار دارد.

توجه داشته باشید که در این حالت، abicompat توابع یا متغیرهای (نمادهای) صادرشده‌ای را که برنامه انتظار دارد اما از کتابخانه حذف شده‌اند، تشخیص نمی‌دهد. به همین دلیل به آن حالت ضعیف (weak) می‌گویند.

کد خروج دستور abicompat در صورتی که ABI باینری‌های مورد مقایسه یکسان باشد برابر با 0 است، و در صورتی که متفاوت باشند یا ابزار با خطایی مواجه شود، غیر صفر خواهد بود.

در حالت دوم، کد خروج یک میدان بیتی ۸ بیتی است که در آن هر بیت معنای خاصی دارد.

بیت اول، با مقدار 1 و نام ABIDIFF_ERROR، به معنای وقوع خطا است.

بیت دوم، با مقدار 2 و نام ABIDIFF_USAGE_ERROR، به این معناست که در نحوه فراخوانی ابزار توسط کاربر خطایی وجود داشته است. برای مثال ممکن است در صورتی تنظیم شود که کاربر ابزار را با یک سوییچ خط فرمان ناشناخته، با تعداد نادرست آرگومان و غیره فراخوانی کرده باشد. اگر این بیت تنظیم شده باشد، بیت ABIDIFF_ERROR نیز باید تنظیم باشد.

بیت سوم، با مقدار 4 و نام ABIDIFF_ABI_CHANGE، بدان معناست که ABI باینری‌های مورد مقایسه متفاوت است.

بیت چهارم، با مقدار 8 و نام ABIDIFF_ABI_INCOMPATIBLE_CHANGE، به این معناست که ABI باینری‌های مقایسه‌شده به نحوی ناسازگار تغییر کرده است. اگر این بیت تنظیم شود، بیت ABIDIFF_ABI_CHANGE نیز باید تنظیم باشد. اگر ABIDIFF_ABI_CHANGE تنظیم شده و ABIDIFF_INCOMPATIBLE_CHANGE تنظیم نشده باشد، بدین معناست که ABIهای مقایسه‌شده ممکن است سازگار باشند یا نباشند. در این حالت، یک انسان باید تغییرات ABI را بررسی کند تا در مورد سازگاری یا عدم سازگاری آنها تصمیم بگیرد.

بیت‌های باقی‌مانده در حال حاضر استفاده نمی‌شوند.

•
تشخیص یک ناسازگاری احتمالی ABI در نسخه جدیدی از کتابخانه مشترک:
$ cat -n test0.h
     1  struct foo
     2  {
     3    int m0;
     4
     5    foo()
     6      : m0()
     7    {}
     8  };
     9
    10  foo*
    11  first_func();
    12
    13  void
    14  second_func(foo&);
    15
    16  void
    17  third_func();
$
$ cat -n test-app.cc
     1  // Compile with:
     2  //  g++ -g -Wall -o test-app -L. -ltest-0 test-app.cc
     3
     4  #include "test0.h"
     5
     6  int
     7  main()
     8  {
     9    foo* f = first_func();
    10    second_func(*f);
    11    return 0;
    12  }
$
$ cat -n test0.cc
     1  // Compile this with:
     2  //  g++ -g -Wall -shared -o libtest-0.so test0.cc
     3
     4  #include "test0.h"
     5
     6  foo*
     7  first_func()
     8  {
     9    foo* f = new foo();
    10    return f;
    11  }
    12
    13  void
    14  second_func(foo&)
    15  {
    16  }
    17
    18  void
    19  third_func()
    20  {
    21  }
$
$ cat -n test1.h
     1  struct foo
     2  {
     3    int  m0;
     4    char m1; /* <-- a new member got added here! */
     5
     6    foo()
     7    : m0(),
     8      m1()
     9    {}
    10  };
    11
    12  foo*
    13  first_func();
    14
    15  void
    16  second_func(foo&);
    17
    18  void
    19  third_func();
$
$ cat -n test1.cc
     1  // Compile this with:
     2  //  g++ -g -Wall -shared -o libtest-1.so test1.cc
     3
     4  #include "test1.h"
     5
     6  foo*
     7  first_func()
     8  {
     9    foo* f = new foo();
    10    return f;
    11  }
    12
    13  void
    14  second_func(foo&)
    15  {
    16  }
    17
    18  /* Let's comment out the definition of third_func()
    19     void
    20     third_func()
    21     {
    22     }
    23  */
$
•
کامپایل نسخه‌های اول و دوم کتابخانه‌ها: libtest-0.so و libtest-1.so:
$ g++ -g -Wall -shared -o libtest-0.so test0.cc
$ g++ -g -Wall -shared -o libtest-1.so test1.cc
•
کامپایل برنامه و پیوند دادن آن با نسخه اول کتابخانه، برای ساخت باینری test-app:
$ g++ -g -Wall -o test-app -L. -ltest-0.so test-app.cc
•
اکنون از abicompat استفاده کنید تا ببینید آیا libtest-1.so با توجه به ABI نسخه libtest-0.so، با برنامه سازگاری ABI دارد یا خیر:
$ abicompat test-app libtest-0.so libtest-1.so
ELF file 'test-app' might not be ABI compatible with 'libtest-1.so' due to differences with 'libtest-0.so' below:
Functions changes summary: 0 Removed, 2 Changed, 0 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
2 functions with some indirect sub-type change:
  [C]'function foo* first_func()' has some indirect sub-type changes:
    return type changed:
      in pointed to type 'struct foo':
        size changed from 32 to 64 bits
        1 data member insertion:
          'char foo::m1', at offset 32 (in bits)
  [C]'function void second_func(foo&)' has some indirect sub-type changes:
    parameter 0 of type 'foo&' has sub-type changes:
      referenced type 'struct foo' changed, as reported earlier
$
•
اکنون از حالت ضعیف abicompat استفاده کنید، یعنی تنها مشخص کردن برنامه و نسخه جدید کتابخانه:
$ abicompat --weak-mode test-app libtest-1.so
functions defined in library
    'libtest-1.so'
have sub-types that are different from what application
    'test-app'
expects:
  function foo* first_func():
    return type changed:
      in pointed to type 'struct foo':
        size changed from 32 to 64 bits
        1 data member insertion:
          'char foo::m1', at offset 32 (in bits)
$

Dodji Seketeli

2014-2025, Red Hat, Inc.

May 1, 2026