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で試して、どちらも挙動は同じでした。