OpenGL 動かなくなった→復旧

研究室でだいぶ前に作った共有3D仮想環境の画面スナップショットが必要になったんで、久しぶりに起動してみたら……ありゃ? Segmentation fault?

前に動かした時からプログラムはいじっていないはず。ほかのアプリケーションはどうかなと思って、調べてみると glclock も動かない。glxgears とかはちゃんと動いてるんだけどなぁ。たぶん、この前の portupgrade で Xorg とかのバージョンが上がったが原因だろうけど、戻すのも非常にめんどうなんで、何とか動かないか悪戦苦闘してみた。

まずは gdb でどこで落ちてるか確認。……って、gluBuild2DMipmaps の中でですかい。(詳しくは gluBuild2DMipmaps から呼ばれる gluTessErrorString とかいう関数の中の strtod() でみたいだけど)

その後、ソースのほうにデバグコードを入れたり、gdb で追跡したりしていると気付いたのが、そもそも glGenTextures がちゃんと機能していないためにテクスチャオブジェクトが生成されていないらしい。

GLuint texture = 12345; /* テストのため適当に初期化 */
glGenTextures(1, &texture);

なんてコードを試してみると、texture の値は12345のままだけど、glGetError で調べてもエラーは発生していない様子。さらに第一パラメータに -1 を指定してみても、やっぱりエラーにならないしで、とにかく変な状態。

その後、OpenGL 関係のAPIがことごとく機能していないことが判明。あらら? でも、MesaDemo のデモは全部動いてるよなぁ。glclock は駄目だけど……。

とかいう具合に、いろいろ調べて丸二日。今日の帰りの電車の中で原因を発見。

とりあえず、MesaDemo の簡単なプログラムを使って、エラー確認のためのコードを追加しながらおかしなところがないか確認しようと思ったところ、単体でコンパイルすると segmentation fault が発生。ldd でちゃんと動いているものとの違いを見てみると、libpthread が足りないことが判明した。

ということで、共有3D仮想環境のツールも CFLAGS に -pthread を追加して make したら、あっさりと正常動作しました。ports/UPDATE には何も書いてなかったと思うけどなぁ。ま、動くようになったからいいか。