GTKのせいでハマったつもりが…

今日は(書類上の)所属団体の設立記念日で休みだった。ので、恵比寿に映画を見に行ったのだが、昨日の時点で(基本的なところは)書き終えたプログラムが、非常に納得のいかない挙動をしていたのが気になって、夜から職場に顔を出した。*1

ということで、例によって以下はプログラムの使えないトホホ話。

わざわざ夜にやってきて、プログラムを見直していたのだが、どうにも腑に落ちない。落ちている場所はrecv()のように見えるのだが、デバッガ様は「gobject-x.x.dllで落ちてるで」と言っている…サーバ側までデバッグコード追加して試してみたが、やはり落ちているのは通信部分ではないようだ。まぁ一応send()もrecv()も戻り値のチェックは(ほぼ)毎回してるしね。面倒だから100%毎回じゃないけど。(←そういうのがダメプログラムの元凶というのは承知の上)

実は、以前にX11でも同様に「ここで落ちる理由がわからん」みたいなことがあって(ただし、その時は再現性が低くて「微妙に不安定」というレベルだったが)、調べまくったら「Xlibの動作はデフォルトではthread safeじゃない。thread safeにするには一番最初にXInitThreads()を呼ぶべし」なるナイスな記述を見かけ、そいつを呼んだら一発で解決したことがあった。

ってことで、また俺がthreadを使ってる絡みでGTK管理下のメモリの中身がおかしくなったのか?そうなのか?という気になる。recv()呼んでるのはthread内だし。その辺りをキーワードに調べると「GTKでthread safeにするにはg_thread_init()やら何やらthread safe用設定関数がある」とかいう話だ。あぁ、やっぱりね。思った通りだよ。早速やってみよう。…ええと、何も解決しませんが?しょうがないので「とにかくDLLってところがデバッグをやりにくくしてるよなー」とか思いつつ、printf攻撃をしてみた。あれれ?なんか思ってた場所よりももっと先まで行ってるじゃん。recv()してその先の処理もやってたのか?おぉっ?こんな先まで行ってたの?…ええと…お?なんかgtk widgetを参照してるな。ここが癌なのか?何で変数を参照しただけで落ちるんだよ!! . . . あ、このタイミングでこのwidgetを参照しちゃダメじゃん

誰に謝ってるのかわからんが、とりあえず「大変申し訳ありませんでした」という気分になった…

*1:今日になって思ったのだが、日中に顔を見なかった人が夜8時過ぎにやってきても、「あれ?どうしたの?」みたいな反応が一切無く、ごく自然に「そういえばさー」みたいに話しかけてくる、うちの職場って…