C/C++ で exit() を呼ぶ2011年03月03日 12時25分15秒

C/C++ で exit を複数回呼び出した時の動作は未定義になっている。未定義とはいえ、AIX と Solaris 上では、不定期にクラッシュを起こす。落ち方も複数あり、segmentation fault か Illegal instruction になることが多いようだ。core をデバッガで覗くと、exit 関数を指している事が多い。

マルチスレッドが存在する前の C では、わざわざ exit を何回も呼び出す必要はなかったが、最近では出来の悪いライブラリがスレッドから勝手に呼び出して、勝手に殺される事がある。まあ、プロセスを殺している時に、プロセスが落ちるのだから、大きな実害が無い場合も多いのだが、無作法極まりない。

プロセスが落ちる主な理由は、広域変数として存在するクラスが破棄された事による事が多い。最近、なぜか好んで使われるシングルトン等もその対象になる。exit 関数が実行され、atexit の関数が呼ばれる。そして、これらの広域変数のクラスが破壊された後で、これらのクラスから関数が呼ばれたりするとポインタなどが 0 になっいて、仮想テーブルを用いたときに、不正なアドレスになる。また、仮想関数を使っていると、Pure virtual function called 等と言った珍しいエラーを目にすることさえある。

結論を知ってしまうと単純なのだが、前知識も無くこの現象に遭遇すると原因の発見がとても難しい。プロセスの落ち方が一定せず、core を見ても取り立てて目立つものが無い。他所で開発されたライブラリが悪さをしてて、そのがらくたから発掘しなければならないので、かなりの困難を伴った。