Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Comparing ABIs for Compatibility with libabigail - Part 2

October 28, 2014
Dodji Seketeli
Related topics:
Linux
Related products:
Red Hat Enterprise Linux

Share:

    In the first article of this series of two, we ran abidiff to compare the ABIs of the libstdc++.so shared libraries from RHEL 6.5 and RHEL 7.  In this article, we are going to analyze the resulting ABI change report that was emitted.

    circles

    Analyzing the results

    The report starts with a header that summarizes the ABI differences:

    Functions changes summary: 0 Removed, 10 Changed (1260 filtered out), 112 Added functions
    Variables changes summary: 0 Removed, 3 Changed (72 filtered out), 97 Added variables
    

    From the:

    Functions changes summary: 0 Removed,

    and:

    Variables changes summary: 0 Removed,

    parts of the header, we understand that all the global variables and functions exported in 6.5 are still present in 7. This an important characteristic to have from an ABI compatibility point of view. It implies that applications that assume the presence of certain exported functions or variables from the RHEL 6.5 version are assured to still find these functions and variables in the RHEL 7 version.

    Of course, libstdc++.so in RHEL 7 adds many new global variables and functions. We can see that from these parts of the header:

    Functions changes summary: [...] 112 Added functions

    and

    Variables changes summary: [...] 97 Added variables

    This is expected from a new release that adds new features and will not cause any ABI incompatibility because applications that were dynamically linked against the RHEL 6.5 version will not be affected by the new global variables and functions added in RHEL 7.

    An interesting part of this header is

    Functions changes summary: [...] 10 Changed (1260 filtered out)

    This is about functions whose sub-types may have changed in ways that don't alter the signature of the function. The sub-type of a function is either its return type or the type of its parameters.

    To better understand the kind of changes abidiff is reporting about here, let's suppose we have a function named func that is exported by a shared library libf.so. The declaration of func would be:

    void func(struct S*);

    Where struct S is defined as:

    struct S
    {
      int i;
    };
    

    Now suppose that in a subsequent version of libf.so, one data member is added to struct S. It would thus become:

    struct S
    {
      char c;
      int m;
    };
    

    We can see that this change doesn't alter the signature of function func which still is:

    void func(struct S*);

    But the struct S that is pointed to by struct S* has changed, possibly in an ABI incompatible way. In other words, function func has a sub-type (struct S) that has changed. And it's this kind of sub-type changes that the abidiff report header refers to when it indicates:

    Functions changes summary: [...] 10 Changed (1260 filtered out)

    One interesting detail of this part of the header is the (1260 filtered out) item.  It indicates that 1260 changes were filtered out from the report, presumably because they are deemed "harmless" from an ABI compatibility point of view. These are typically changes like a data member that was declared public and now becomes private. Curious users can force abidiff to show these harmless changes by using the --harmless command-line option. It's worthwhile to notice that filtering out this huge number of harmless changes greatly helps to spot the potentially harmful ones that would otherwise be buried in the noise.

    Further on in the report, we see 4 additional sections that provide details about the actual changes:

    1. Details of the added functions:

    112 Added functions:
    
    [A] 'function __cxxabiv1::__cxa_dependent_exception* __cxxabiv1::__cxa_allocate_dependent_exception()' {__cxa_allocate_dependent_exception@@CXXABI_1.3.6}
    [A] 'function void __cxxabiv1::__cxa_deleted_virtual()' {__cxa_deleted_virtual@@CXXABI_1.3.6}
    [A] 'function void __cxxabiv1::__cxa_free_dependent_exception(__cxxabiv1::__cxa_dependent_exception*)' {__cxa_free_dependent_exception@@CXXABI_1.3.6}
    [A] 'function int __cxxabiv1::__cxa_thread_atexit(void*, void*)' {__cxa_thread_atexit@@CXXABI_1.3.7}
    [A] 'function void __cxxabiv1::__cxa_tm_cleanup(void*, void*, unsigned int)' {__cxa_tm_cleanup@@CXXABI_TM_1}
    [A] 'method void __gnu_debug::_Safe_local_iterator_base::_M_attach(__gnu_debug::_Safe_sequence_base*, bool)' {_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17}
    [A] 'method void __gnu_debug::_Safe_local_iterator_base::_M_detach()' {_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17}
    [A] 'method void __gnu_debug::_Safe_unordered_container_base::_M_detach_all()' {_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17}
    [A] 'method void __gnu_debug::_Safe_unordered_container_base::_M_swap(__gnu_debug::_Safe_unordered_container_base&)' {_ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_@@GLIBCXX_3.4.17}
    [A] 'function std::size_t std::_Fnv_hash_bytes(std::size_t, std::size_t)' {_ZSt15_Fnv_hash_bytesPKvmm@@CXXABI_1.3.5}
    [A] 'function std::size_t std::_Hash_bytes(std::size_t, std::size_t)' {_ZSt11_Hash_bytesPKvmm@@CXXABI_1.3.5}
    [A] 'method void std::_List_node_base::_M_hook(std::_List_node_base*)' {_ZNSt15_List_node_base7_M_hookEPS_@@GLIBCXX_3.4.14}
    [A] 'method void std::_List_node_base::_M_reverse()' {_ZNSt15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14}
    (... the rest of the 112 added functions are not shown ...)
    

    In this section, abidiff shows the signatures of the functions that were added. For each added function it also shows the ELF symbol name of that function, inside curly brackets, including it's versioning information e.g, {__cxa_allocate_dependent_exception@@CXXABI_1.3.6}

    2. Details of any function whose signature has not changed, but which contains changes in some sub-type. For the sake of conciseness, let's focus on some interesting bits exhibited in the report. For instance:

    [C]'method void std::condition_variable::wait(std::unique_lock<std::mutex>&)' has some indirect sub-type changes:
      parameter 1 of type 'std::unique_lock&' has sub-type changes:
        in referenced type 'class std::unique_lock':
          1 data member change:
            type of 'std::mutex* std::unique_lock::_M_device' changed:
              in pointed to type 'class std::mutex':
                entity changed from class std::mutex to typedef std::unique_lock::mutex_type
                  1 base class insertion:
                    class std::__mutex_base
    

    This excerpt is basically telling us that the type std::mutex that is now being accessed through the (typedef) naming std::unique_lock<std::mutex>::mutex_type has been changed; it now has one more base class named std::_mutex_base. That change however hasn't modified the size of the class.

    It's also telling us that this class std::mutex related change impacts the data member std::unique_lock<std::mutex>::_M_device, which is of type std::mutex*.

    The enclosing std::unique_lock<std::mutex> type is used by the exported method void std::condition_variable::wait(std::unique_lock<std::mutex>&).

    As reviewers interested in ABI matters, we can now use our judgment and infer that this change is not harmful, mainly because it doesn't change the size of the impacted data types and also because it doesn't change any of the type layouts in an ABI-incompatible way. It's still quite interesting to have it pinpointed as a worthwhile ABI change.

    It's worthwhile to notice how hierarchical the reported items about the type changes are. They mention the exported functions from which the changed types are used and they walk you all the way through how the changed type is used from that public entry point.

    It's also interesting to note how difficult it would have been for reviewers to come up with this kind of ABI impact analysis by just looking at the original source change, which is, the addition of the new base class (std::_mutex_base) to std::unique_lock<std::mutex>::mutex_type. The remaining two sections are about similar topics, but for variables. That is, added variables and variables with sub-type changes. Analyzing them is left as an exercise for interested and coffee loving readers.

    Caveats

    Libabigail and its associated tools are still in their early days. There are ABI changes that are not yet caught. There are debug information constructs that are not yet supported. There can also be issues around the way it interprets those constructs that it does support.

    So the results of running abidiff on libstdc++.so should be taken with rocks of salt.

    That said, substantial work in under way to improve these areas and add features that we know are needed.

    Conclusion

    The Libabigail  based tool-set has already been useful to us internally at Red Hat, even in these early days. Having a hierarchical textual report about the ABI differences of two versions of a library, just by analyzing the content of the binaries, is a great proposition.

    This can empower people responsible for software distributions to perform some deep ABI change impact analysis on the shared libraries they ship, just by looking at the binaries themselves. Libabigail being a re-usable library itself, these people can now envision building their own derivative tools to help themselves.

    Or so we wish.


     

    Hopefully, having read this article, you have a deeper understanding of the significant challenges in the area of ABI compatibility, as well as the significant investment Red Hat makes in developing solutions to some of the related problems. Naturally, these tools are all shared openly with the community.

    We welcome feedback! If you have any questions or comments relating to this article, please feel free to add it below or contact us.

    Last updated: April 5, 2018

    Recent Posts

    • Install Python 3.13 on Red Hat Enterprise Linux from EPEL

    • Zero trust automation on AWS with Ansible and Terraform

    • Cloud bursting with confidential containers on OpenShift

    • Reach native speed with MacOS llama.cpp container inference

    • A deep dive into Apache Kafka's KRaft protocol

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue