なぜLinuxプログラムderefrences(char*)0は常にsegfault?
-
20-09-2019 - |
質問
いたコードがありますが、ここでは検出が子プロセスはsegfaulted.私の想像がってこのコードは常にsegfault:
#include <stdio.h>
int main() {
char *p = (char *)(unsigned long)0;
putchar(*p);
return 0;
}
感動でDebian Linux2.6.26kernel;私はシェルのAT&T ksh93
からDebian ksh
パッケージ、バージョンM93s+2008-01-31.このプログラムsegfaultがそうでない場合は単に終了し黙って、ゼロ以外の終了ステータスがメッセージ。私の信号検出プログラム報告書の
segfault terminated by signal 11: Segmentation fault
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 11: Segmentation fault
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
走行下での純 ksh
このsegfaultも珍しい:
Running...
Running...
Running...
Running...
Running...
Running... Memory fault
Running...
興味深いことに、 bash
正しく検出しsegfault時.
私の質問:
誰でもできるので説明す。
誰でもできるので提案プCプログラムsegfaultにより確実に執行?もし
kill(getpid(), SIGSEGV)
, がんに類似す。
編集: jbcreixの回答:私segfault検出器の破となりました。私の興奮で ksh
同じ問題です。っと bash
や bash
がでます。
私のイメージを持ったパ WNOHANG
へ waitpid()
, 私がすべて通過ゼロになります。どうなるかはわからないか考えて!思うので、 ksh
, が、それは別の質問です。
解決
のNULL
するのを書くことは確実セグメンテーションフォールトやバスエラーになります。
時々、OSはゼロアドレスに読み取り専用のページをマップします。したがって、あなたは時々NULL
から読み取ることができます。
NULL
アドレスを定義しますが、、その特別な地位の「実装は」実際のオペレーティングシステムの仮想メモリ(VM)サブシステムによって処理されます。
WINEとはdosemuは、Windowsとの互換性のためNULL
でページをマップする必要があります。この操作を行うことができないカーネルを再構築するためにLinuxカーネルにmmap_min_addr
を参照してください。
mmap_min_addr
は、OpenBSDの努力のテオ・デ・ラートから(明らかに、Linuxの名声の、)ライナスに向かって公共炎、原因に関連する現在話題悪用であります。
、いつでも呼び出すことができます。raise(SIGSEGV);
また、あなたからの保証・ツー・セグメンテーションフォルトのポインタを取得することができます。
int *ptr_segv = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS, -1, 0);
ここでPROT_NONE
にアクセスすることができないメモリを予約するための鍵です。 32ビットIntel Linuxの場合、PAGE_SIZEは4096です。
他のヒント
私はそれが一貫性のある行動を持っていない理由はわかりません。私はそれがNIT-うるさい読書のようにではないと思うだろう。またはそのような何か、けれども私はおそらく完全に間違っていると思います。
NULLで書いてみてください。これは私のために一貫しているようです。私はあなたがこのかかわらずを使用したいと思います理由はわかりません。 :)
int main()
{
*(int *)0 = 0xFFFFFFFF;
return -1;
}