私はバグのあるコードを処理していましたが、クラッシュに関する詳細情報を得るためにSIGSEGVハンドラをインストールしたかったのです。しかし、私はハンドラが呼び出されていないことに気付きました。破損したスタックによってトリガされたSIGSEGVの取得
私は理由を探していて、スタックポインタの値が壊れていると思われます(マスクされていません)。ここで私が確認するために書いたいくつかの概念実証コードがあります:
static void catch_function(int sig, siginfo_t *info, void *cntxt)
{
puts("handler works");
}
void main(int argc, char **argv)
{
struct sigaction sa;
sa.sa_sigaction = (void *)catch_function;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO | SA_NODEFER ;
sigaction(SIGSEGV, &sa, NULL);
puts("testing handler");
raise(SIGSEGV);
puts("back");
__asm__ ( "xor %rax, %rax\n\t"
"mov %rax, %rsp\n\t"
"push 0"
);
// never reached...
}
アイデアは(オフセット無効)0にRSPを設定し、何かのためにそれを使用することです。しかし、この2番目のSIGSEGVはハンドラによって捕捉されず、代わりにプロセスを終了します。
どうやら、シグナルハンドラを起動するには、まずは正式なスタックポインタが必要ですが、どうしてですか?これは信号を扱うという考え方に反していないのですか?これを回避する可能性はありますか?
私はLinuxバージョン3.19.0-25-ジェネリックを実行しています。
'sigaltstack()' – EOF
@ EOF - ありがとう。有望に見える。成功すると解決策を投稿します。 – HairyNopper
valgrind内でプログラムを実行できますか? – bruceg