2023年5月末でUbuntu 18.04のサポートが終了しました。それに伴い、Ubuntu 18.04からUbuntu 20.04にアップグレードを行いましたが、Ubuntu 18.04では動作していたC++で開発したROSプログラムがUbuntu 20.04でコンパイルおよび実行した際にプログラムが強制終了する問題が発生しました。本記事では、この問題の原因について説明します。

1. 原因

プログラムが強制終了した原因は、Ubuntuのバージョンアップに伴い、C++コンパイラ(gcc)のバージョンが変更されたことで、非void関数でreturnコードが記述されていない誤りのあるソースコードがエラーとして処理されるようになったためです。具体的には、Ubuntu 18.04のC++コンパイラはgcc 7を使用していましたが、Ubuntu 20.04ではgcc 9に変更になりました。このバージョンの変更により、以前は動作していたプログラムが動作しなくなりました。

2. バージョンの違いによる挙動の差

以下は問題を再現するために作成したプログラムの例です。
test_example

#include <ros/ros.h>
#include <iostream>

int testFunction()
{
    // returnコードが省略された場合
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "example_node");
    ros::NodeHandle nh;

    int result = 0;
    testFunction();
    ROS_INFO_STREAM("Result: " << result);

    ros::spin();

    return 0;
}

上記プログラムをUbuntu 18.04とUbuntu 20.04で実行すると以下の様な結果になります。
【Ubuntu 18.04】

rosrun test_example test_example
[ INFO] [1687394783.499485737]: Result: 0

【Ubuntu 20.04】

rosrun test_example test_example
free(): invalid pointer
中止 (コアダンプ)

Ubuntu 20.04で実行をすると、プログラムの15行目で強制終了します。

Ubuntu 18.04ではデフォルトでgcc 7、Ubuntu 20.04ではgcc 9がインストールされます。
gcc 7では、非void関数でreturnコードがない場合でも、プログラムを実行できていました。しかし、gcc 8以上ではこの仕様が変更され、該当する場合にはセグメンテーションフォールト(Segmentation Fault)が発生するようになりました。この変更により、ROSプログラムが強制終了しました。
 
以下がUbuntu 18.04と20.04のC++コンパイラのバージョンになります。
 
【Ubuntu 18.04】

g++ --version
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【Ubuntu 20.04】

g++ --version
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 
Ubuntuのバージョンアップは機能の向上などの利点をもたらしますが、互換性の問題が生じる場合もあります。
C++で開発したROSプログラムの実行時に強制終了する問題もその一例です。
今回、互換性の問題に直面しましたので掲載してみました。皆様のお役に立てれば幸いです。