採用情報

お問い合わせ

BLOG

Linux の知識・学習 BLOG

Linux の知識・学習 BLOG

2024 年 02 月 20 日

ABI 互換が壊されてしまうとき。どのような場合に非互換になるのか?:ABI 互換性解説付記

例 1: 依存する共有ライブラリの仕様変更によって起こる非互換

これは ABI 互換を保つ上で最も気をつけるべきポイントです。共有ライブラリはその性質上、機能を共通化し、他のアプリケーションから呼び出されることを目的に作られており、そうそう仕様は変わりませんが、時に機能が時代の変化とともに不要になったり、非推奨としなければならない機能が発見されたり、はたまたメンテナンスコストの削減のためコードそのものを削除するなどの理由で、外部向けのインターフェイスである API/ABI にも変更が入ることは年単位で見れば、ままあります。また実験的な実装として不安定なことを予め告知されている機能などは、より良いコードが実装されれば あっさりと切り捨てられる可能性もあります。

例 2:C++ コンパイラのバージョンの違いによって起こる非互換

ビルド時に用いるコンパイラはバイナリの構造について考えるときに無視できない要素の一つです、過去から現在にいたるまで存在したコンパイラで最も影響力があるのは GNU プロジェクトが開発している GNU Compiler Collection( 以下、GCC) と言っても過言ではないでしょう。そのためシステムコンパイラとしての GCC のバージョンに依存する ABI について解説します。

メジャーなプログラミング言語の一つである、C++ の機能は標準ライブラリ (libstdc++) に依存しており、GCC のバージョンによって非互換なことが公式ドキュメントに記されています。

この記述によると、GCC 3.1.0(2002 年 5 月リリース ), GCC 3.2.0(2002 年 8 月リリース ), GCC 3.4.0(2004 年 4 月リリース ) はそれぞれ、libstdc++ に非互換な ABI 変更が入り、SO(Shared Object) のメジャーバージョンが加算されています。

また Gentoo の wiki には面白いトラブルシューティングが載っています。

この記述によると、GCC 4.1(2006 年 2 月リリース ) や 5.1(2015 年 4 月リリース ) へそれ以前のバージョンから GCC をアップグレードした場合、ABI の問題に直面するため libstdc++ に依存するアプリケーションやライブラリをすべてリビルドする手順を案内しています。
また GCC は ABI の安定性を保証しようとしますが、libstdc++ のすべてがその対象となるわけではなく、例えば C++11(2011 年に発行された C++ の規格の一つです ) の ABI の安定性は GCC 5.1 以降でのみ提供されているということです。
EL9 系の GCC のバージョンは 11 系で、C++14 や C++17( 実験的かつ不完全ですがそれ以降の標準規格も ) をコンパイルすることができます。しかし同じ ( あるいは近似した ) バージョンを使ってビルドしなければ、ABI 互換を完全に保証するのは困難でしょう。

例 3: macOS のシステムコールの仕様変更

2016 年にリリースされた macOS Sierra では珍しい非互換な変更が行われ、
一部の macOS 向けにビルドされた実行コードの一部が正しく動作しなくなるという問題が起こりました。その原因は gettimeofday(2) というシステムコールの返り値の仕様が変更されたことでした。
標準 C ライブラリのようなラッパーを通したプログラミング言語で書かれたコードは直接の影響はありませんでしたが、例えば Go 言語のように OS が提供するラッパーを通さず、言語側でシステムコールを直接呼び出している言語は 影響を受け 呼び出しを行うコードが修正されました。言い換えれば macOS は Sierra 以前と以後で ABI に非互換性があるとも言えるでしょう。

本記事に関連するリンク
AlamLinux OS サポートサービス ご相談・お問い合わせ
CentOS 7 延長サポートサービス
デジタルトランスフォーメーションのための電子認証基盤 iTrust
SSL/TLS サーバー証明書 SureServer Prime