Skip to main content

ログ取得ツール (移転先予定地)

C++でdivide by zeroを例外としてcatchするにはどうしたらいいだろうか

LinuxでC++を使うとき、gccのg++を使うことが多いだろう。でもいまいち使ってない。なぜか。例外がcatchできないからだろうと思った。というわけで。

C++でdivide by zeroやNULL pointer dereference等はtry〜catchで挟んでも例外としてはcatchできず、普通にシグナルハンドラに落ちる。どうしたらいいのか。

シグナルハンドラを登録してそっから投げりゃいいんじゃねえの?? と思って、そう書いてみた。

#include #include extern “C”{ #include #include };

using namespace std;

class sigexception{ int val; public: sigexception(int a){ val=a; } int getvalue(){ return val; } char *getstring(){ return strsignal(val); } };

void sighandle(int a) throw(sigexception) { throw sigexception(a); }

int main(int argc, char **argv) { signal(SIGINT, sighandle); signal(SIGFPE, sighandle); signal(SIGSEGV, sighandle); signal(SIGBUS, sighandle); …. }

で、try{ sleep(10000); }catch(sigexception e){}みたいにして、killコマンドでシグナルを投げてみると、普通にcatchできた!!

と思ったけど、1/0とか計算して本物の例外を出してみるとダメでした。シグナルハンドラ(上のコードで言うsighandle)は起動するんだけど、terminate called after throwing an instance of ‘sigexception’ とか言われ、例外はcatchできずに落ちる。どうしてそうなんだろう…。

コンパイルするときに「-fexceptions」をつけてもダメ。Fedora Core 3のgcc-c++-3.4.3-22.fc3とgcc4-c++-4.0.0-0.41.fc3で試して、どちらも挙動は同じでした。