2012-01-04 48 views
0

私はスタックに何かを書き込もうとすると、次のコードを持っています。私はスタックの一番下に書きます。まだアプリケーションは触れていません(スタックは下に向かって成長し、stackaddrはここを指しています)。ここでセグメンテーションフォルトが発生するのはなぜですか?

しかし私も両方の書き込みを与えることMPROTECTをやった後、セグメンテーションフォールトを取得し、そのメモリ領域へのアクセス権をお読みください。コンパイルフラグ-fno-stack-protectorを使用しても、セグメンテーション違反が発生します。ここで何が起きてるの?

pthread_attr_t attr; 
void * stackaddr; 
int * plocal_var; 
size_t stacksize; 

pthread_getattr_np(pthread_self(), &attr); 
pthread_attr_getstack(&attr, &stackaddr, &stacksize); 

printf("stackaddr = %p, stacksize = %d\n", stackaddr, stacksize); 

plocal_var = (int*)stackaddr; 
mprotect((void*)plocal_var, 4096, PROT_READ | PROT_WRITE); 
*plocal_var = 4; 
printf("local_var = %d!\n", *plocal_var); 
+5

あなたの質問が何であるかを少なくとも示唆するタイトルを試してみてください。 – Mat

+0

'stackaddr'の値を表示し、'/proc/pid/maps'を見てそこに実際にメモリがマップされていることを確認してください。また、 'mprotect'の戻り値を確認してください。おそらく手がかりを与えるでしょう。 –

答えて

3

あなたはほぼ確実にまだマップされていないmprotect()ページにしようとしています。戻りコード:mprotect()はおそらく-1を返し、errnoENOMEMに設定する必要があります(これはmprotect(2) man pageに記載されています)。

スタックページはオンデマンドでマップされますが、カーネルは現在のスタックポインタ以上のアクセスによって引き起こされたページフォールトを区別するのに十分なほど巧妙です(スタックを下に拡張する有効な試行新しい値から何らかの正のオフセットへの読み取りまたは書き込みを実行する)、およびスタックポインタの下のアクセスによって引き起こされたページフォールト(有効でない)を含む。