前回の続き、・・・なのか?
前回をふまえてか、シグナルハンドラでPIPEにメッセージを書き、mainのループでPIPEからメッセージを読み処理を行うというオーソドックスな構造になっていた。ただ、SITERMを受けたときの挙動がものすごく怪しかった。
SIGTERMを受けると例のごとくアプリの終了のためのリソース回収用関数を呼ぶようになっていたが、その関数の中で真っ先に、シグナルのメッセージのやりとり用PIPEを閉じていた。案の定、閉じた後にシグナルを受けるとシグナルハンドラでPIPEに書こうとし、シグナルハンドラ内でSIGPIPEを起こして結果SIGKILLで死んでいた。おまいはこの実装で、1秒周期にsetitimerで設定したSIGALRMから逃げられると思ってたのかよ。
とりあえずPIPEのcloseをコメントアウトしてさらに挙動を追うと、今度は一度freeで解放したリストを二度freeしようとしてSIGSEGVで死んでいた。freeしたらすぐにNULLを入れておきましょうとよい子は習わなかったのか?
これでやっと終わりと持ったら、次はmallocしたリソースを解放するループで境界値ミスして二重freeしようとしSIGSEGVで死んでいた。ナニコレ・・・
二重freeしたときにどんな挙動をするのかの解析をやらされているこちらの身にもなってくださいってば。SIGSEGVで死ねばいい方で、場合によっちゃfree内部で無限ループで固まっちゃうし。とりあえずあれだ、closeとかfreeとかしかしてないんだから、SIGTERMをハンドルしようとか思わずに潔くそのまま死んでください。その方がみんなのためなので。てか、死ぬのはそのプロセスじゃあくておまいn(省略されました・・全てを読むにはらるるをなぐさめてやってください。)
とか思いながら適当にググってたら、小崎さんが語っていた。「普通の人はmallocのソースなんて読まない」とか言ってた (´・ω・`) 参考にさせてもらいました。。
2015/05/07追記 上記からは動画が消えてますが、Youtubeに残ってます。