「バス エラー」メッセージの意味と、セグメンテーション違反との違いは何ですか?
18 に答える
現在、x86 でバス エラーが発生することはまれであり、プロセッサが要求されたメモリ アクセスを試みることさえできない場合に発生します。通常は次のようになります。
- アラインメント要件を満たさないアドレスを持つプロセッサ命令を使用しています。
プロセスに属していないメモリにアクセスすると、セグメンテーション違反が発生します。それらは非常に一般的であり、通常は次の結果です。
- 割り当て解除されたものへのポインターを使用します。
- 初期化されていないため、偽のポインターを使用しています。
- ヌルポインタを使用。
- バッファのオーバーフロー。
PS: より正確に言えば、問題を引き起こすのはポインター自体を操作することではありません。それが指すメモリにアクセスしています(逆参照)。
segfault は、アクセスが許可されていないメモリにアクセスしています。読み取り専用、権限がないなど...
バス エラーが、おそらく存在しないメモリにアクセスしようとしています。システムにとって意味のないアドレスを使用したか、その操作に対して間違った種類のアドレスを使用しました。
アプリケーションがデータバス上でデータのミスアライメントを示すと、カーネルが SIGBUS を発生させると思います。ほとんどの [?] ほとんどのプロセッサ用の最新のコンパイラは、プログラマーのためにデータをパディング/アラインするため、(少なくとも) 昔のアラインメントの問題が軽減されたため、最近では SIGBUS があまり見られなくなったと思います (AFAIK)。
差出人:こちら
バス エラーの典型的な例の 1 つは、 SPARCなどの特定のアーキテクチャ(少なくとも一部の SPARC、おそらくこれは変更されている) で、ミスアライメント アクセスを行った場合です。例えば:
unsigned char data[6];
(unsigned int *) (data + 2) = 0xdeadf00d;
0xdeadf00d
このスニペットは、(ほとんどの場合) 適切にアラインされていないアドレスに32 ビット整数値を書き込もうとしており、この点で「うるさい」アーキテクチャではバス エラーが発生します。ちなみに、Intel x86 はそのようなアーキテクチャではありません。アクセスが許可されます(実行は遅くなりますが)。
OS、CPU、コンパイラ、およびその他の要因によって異なります。
一般に、これは CPU バスがコマンドを完了できなかったか、競合が発生したことを意味しますが、環境や実行中のコードに応じて、さまざまな状況が発生する可能性があります。
これは通常、アラインされていないアクセスを意味します。
物理的に存在しないメモリにアクセスしようとするとバス エラーが発生しますが、MMU を搭載したプロセッサとバグのない OS を使用している場合、これは発生しません。 -プロセスのアドレス空間にマップされた既存のメモリ。
Mac OS X でのバス エラーの原因は、スタックに約 1Mb を割り当てようとしたことです。これは 1 つのスレッドではうまく機能しましたが、openMP を使用すると、Mac OS X では非メイン スレッドのスタック サイズが非常に制限されているため、バス エラーが発生します。
私の場合、アセンブリが.text
セクションに戻ることを宣言しなかったために、誤って「バス エラー」が発生しました。当たり前のように思えるかもしれませんが、しばらくの間、私は困惑しました。
例えば。
.globl _myGlobal # Allocate a 64-bit global with the value 2
.data
.align 3
_myGlobal:
.quad 2
.globl _main # Main function code
_main:
push %rbp
データからコードに戻るときにテキスト ディレクティブがありませんでした:
_myGlobal:
.quad 2
.text # <- This
.globl _main
_main:
これが誰かに役立つことを願っています
バス エラーが発生する典型的なバッファ オーバーフローは次のとおりです。
{
char buf[255];
sprintf(buf,"%s:%s\n", ifname, message);
}
ここで、二重引用符 ("") で囲まれた文字列のサイズが buf サイズを超えると、バス エラーが発生します。