バスエラーとセグメンテーション違反の違いは? プログラムがセグ フォールトを発生させて最初に停止し、2 回目にバス エラーを発生させて終了するということは起こり得ますか?
7 に答える
私が使用したほとんどのアーキテクチャでは、違いは次のとおりです。
- SEGV は、意図されていないメモリにアクセスしたときに発生します (たとえば、アドレス空間の外)。
- SIGBUS は、CPU のアラインメントの問題が原因で発生します (たとえば、4 の倍数ではないアドレスから long を読み取ろうとするなど)。
たとえば、ハードウェア バスがサポートしていないことをプログラムが実行しようとすると、バス エラーが発生することがあります。たとえば、SPARCでは、奇数アドレスからマルチバイト値 (int、32 ビットなど) を読み取ろうとすると、バス エラーが発生しました。
セグメンテーション違反は、たとえば、セグメンテーション ルールに違反するアクセスを行った場合、つまり、所有していないメモリを読み書きしようとした場合に発生します。
「断続的に SIGSEGV または SIGBUS を取得していますが、一貫性がないのはなぜですか?」という意味として質問を (おそらく間違って) 解釈すると、C または C++ 標準では、ポインターを使用して危険なことを行うことが保証されていないことに注意してください。セグメンテーション違反; それは単なる「未定義の動作」であり、私がかつて教授として述べたように、代わりにワニが床板から出現してあなたを食べる可能性があることを意味します.
そのため、最初に発生したバグでSIGSEGV が発生することがあり、2 番目のバグ (segfault が発生せず、プログラムがまだ実行されている場合) で SIGBUS が発生するという 2 つのバグが発生している可能性があります。
デバッガーを使用して、ワニに注意することをお勧めします。
Posix で定義されたSIGSEGV
andシグナルについて話していると思います。SIGBUS
SIGSEGV
プログラムが無効なアドレスを参照すると発生します。SIGBUS
実装定義のハードウェア障害です。これら 2 つのシグナルのデフォルトのアクションは、プログラムを終了することです。
プログラムはこれらのシグナルをキャッチし、無視することさえできます。
これはWhat is a bus error?の複製になります。、それがなければ
プログラムがセグ フォールトを発生させて最初に停止し、2 回目にバス エラーを発生させて終了するということは起こり得ますか?
質問の一部。ここにある情報を使用して、自分でこれに答えることができるはずです。
狂気:同じことを何度も繰り返し、異なる結果を期待すること。
- アルバート・アインシュタイン
もちろん、質問を文字通りに受け取って...
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main() {
srand(time(NULL));
if (rand() % 2)
kill(getpid(), SIGBUS);
else
kill(getpid(), SIGSEGV);
return 0;
}
多田、ある実行でセグメンテーション違反で終了し、別の実行でバスエラーで終了する可能性のあるプログラム。