0

無限ループでポインタを増やしている場合、セグメンテーション違反が発生する場所を予測する方法は?

アラーム シグナル ハンドラーを使用でき、1 秒ごとに呼び出され、ポインターが指すアドレスを出力して、セグメンテーション フォールトが発生したときに、発生した非常に近いアドレスを取得できると考えました。

もっと良い解決策はありますか?あれば教えてください。前もって感謝します

コード :

#define SECOND 1

int *str;

void  ALARMhandler(int sig)
{
     signal(SIGALRM, SIG_IGN);      


printf("ptr=%u \n",*str);

     alarm(SECOND);                     /* set alarm for next run   */
     signal(SIGALRM, ALARMhandler);     /* reinstall the handler    */
}



int main()
{

int *ptr;
str=&ptr;
int a;
ptr=&a;
signal(SIGALRM,ALARMhandler);    
alarm(SECOND);                   


for(;;)
{
    ptr++;


}

return 0;

}
4

1 に答える 1

2

まず、最適化レベルが十分に大きい場合、コンパイラは無限for(;;)ループを完全に削除する可能性があります。

毎秒だけポインターを表示することはあまり意味がありません。典型的なプロセッサは、毎秒数十億 (つまり 10 9 ) のマシン命令を実行します。32 ビット マシンでは、これはプロセス アドレス空間全体を数秒でスキャンできることを意味します。

次に、Linux/AMD64 (および Linux/x86) では、スタックは下に向かって (より高いアドレスからより低いアドレスへ) 成長します。呼び出しフレームの近くのローカル変数から開始するため、 mainすぐに外に出ます (つまり、前 = スタックの先頭より上)。

おそらくSIGSEGV信号をキャッチできます。これは、フラグを使用して、 sigaction(2)システム コールでプロセッサおよびシステム固有のハンドラをインストールすることを意味します。SA_SIGINFO

/proc/self/maps実際、Linux では、 (またはproc(5)疑似ファイル システム/proc/self/smaps内の他のファイル)を読み取ることによって、プロセス アドレス マップを取得したい場合があります。これにより、特定のアドレスが属するセグメントが得られ、そのセグメントがどこで終了するかを理解できるようになります。

于 2012-05-21T08:01:43.980 に答える