AddVectoredExceptionHandler

まあでもとりあえず死んだときのipがあればよいか。


さて、昔のWindowsでは例外が起こったときにそれを捕捉するには、SEHとやらを使わねばならず、SEHに対応していないコンパイラを使う場合は、手動でFSレジスタを叩く必要があった。(ちなみにSEH対応は特許に触れるらしく、うかつに実装できない)


が、Windows XP以降は AddVectoredExceptionHandler というものがあって、これを使えば簡単に例外がとれるようだ。
詳しくはMSDNの該当部分参照で

#include <windows.h>

typedef LONG CALLBACK (*PVECTORED_EXCEPTION_HANDLER)(
  PEXCEPTION_POINTERS ExceptionInfo
);

PVOID AddVectoredExceptionHandler(
  ULONG FirstHandler,
  PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

LONG WINAPI handler(struct _EXCEPTION_POINTERS *exc)
{
	PCONTEXT ctxt;
	ctxt = exc->ContextRecord;
	printf("eip = %p\n", (int*)ctxt->Eip);
	exit(1);
}

int main()
{
	PVOID h;
	int *p = 0;
	h = AddVectoredExceptionHandler(1, handler);
	*p = 0;
	RemoveVectoredExceptionHandler(h);
}

TCCだとヘッダに入っていないのでプロトタイプは自分で書く。TCCのヘッダはMingwと同じ気がするので、Cygwin/Mingwも同じかも。

あとkernl32.defにも入っていないので、

LIBRARY kernel32.dll

EXPORTS
AddVectoredExceptionHandler
RemoveVectoredExceptionHandler

こういうdefを書いてリンクする。


これであとは tccデバッグ情報出させて落ちた場所の関数名、行番号…可能ならバックトレースぐらい出せればデバッガはほぼいらないだろう。

問題はtccデバッグ情報が何者なのか…というところだが。まあ、そのうち。これはかなり欲しいのでやる気がする。