「バスエラー」メッセージの意味と、segfaultとの違い
「バスエラー」メッセージの意味と、segfaultとの違い
回答:
最近のx86ではバスエラーはまれであり、プロセッサが要求されたメモリアクセスを試行できない場合に発生します。通常は次のとおりです。
セグメンテーション違反は、プロセスに属していないメモリにアクセスするときに発生します。これらは非常に一般的であり、通常は次の結果です。
PS:より正確には、これは問題を引き起こすポインタ自体を操作しているのではなく、ポイントしているメモリにアクセスしています(逆参照)。
/var/cache
は単にいっぱいでしたaskubuntu.com/a/915520/493379
static_cast
編void *
格納コールバック(メソッドへのオブジェクトと他の1つの属性点)、そのオブジェクトにパラメータを。次に、コールバックが呼び出されます。ただし、渡されvoid *
たものは完全に異なるものだったため、メソッド呼び出しによってバスエラーが発生しました。
mmap
最小限のPOSIX 7の例
「バスエラー」は、カーネルSIGBUS
がプロセスに送信するときに発生します。
ftruncate
忘れられたためにそれを生成する最小限の例:
#include <fcntl.h> /* O_ constants */
#include <unistd.h> /* ftruncate */
#include <sys/mman.h> /* mmap */
int main() {
int fd;
int *map;
int size = sizeof(int);
char *name = "/a";
shm_unlink(name);
fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600);
/* THIS is the cause of the problem. */
/*ftruncate(fd, size);*/
map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
/* This is what generates the SIGBUS. */
*map = 0;
}
次で実行:
gcc -std=c99 main.c -lrt
./a.out
Ubuntu 14.04でテスト済み。
POSIX は次のように説明 SIGBUS
します。
メモリオブジェクトの未定義部分へのアクセス。
MMAPの仕様では、その言葉:
paで始まり、オブジェクトの終わりに続いてlenバイトの間ページ全体に続くアドレス範囲内の参照は、SIGBUSシグナルの配信になります。
そしてshm_open
、それはサイズ0のオブジェクトを生成すると言います:
共有メモリオブジェクトのサイズはゼロです。
そこで*map = 0
、割り当てられたオブジェクトの終わりを超えて触れています。
ARMv8 aarch64での非境界整列スタックメモリアクセス
これは、バスエラーとは何ですか?SPARCの場合ですが、ここではより再現性の高い例を示します。
必要なのは、独立したaarch64プログラムだけです。
.global _start
_start:
asm_main_after_prologue:
/* misalign the stack out of 16-bit boundary */
add sp, sp, #-4
/* access the stack */
ldr w0, [sp]
/* exit syscall in case SIGBUS does not happen */
mov x0, 0
mov x8, 93
svc 0
そのプログラムは、ThunderX2サーバーマシンでUbuntu 18.04 aarch64、Linuxカーネル4.15.0でSIGBUSを発生させます。
残念ながら、QEMU v4.0.0のユーザーモードでは再現できません。理由はわかりません。
障害はオプションであり、SCTLR_ELx.SA
およびSCTLR_EL1.SA0
フィールドによって制御されているようです。ここで関連ドキュメントを少しまとめました。
アプリケーションがデータバス上でデータの不整合を示すと、カーネルがSIGBUSを生成すると思います。ほとんどのプロセッサーのほとんどの[?]現代のコンパイラーは、プログラマーのためにデータをパディング/アラインするので、(少なくとも)ヨアのアラインメントの問題は軽減されたため、最近ではSIGBUSはあまり頻繁に見られません(AFAIK)。
From:ここから
何らかの理由でコードページをページインできない場合にも、SIGBUSを取得できます。
mmap
のサイズよりも大きいファイル/dev/shm
OS XでCをプログラミングしているときに発生したバスエラーの具体例:
#include <string.h>
#include <stdio.h>
int main(void)
{
char buffer[120];
fgets(buffer, sizeof buffer, stdin);
strcat("foo", buffer);
return 0;
}
ドキュメントを覚えていない場合はstrcat
、最初の引数を変更して、ドキュメントが最初の引数に2番目の引数を追加します(引数を反転すると、正常に動作します)。Linuxでは、これはセグメンテーション違反を引き起こします(予想どおり)が、OS Xではバスエラーが発生します。どうして?本当に分からない。
"foo"
はメモリの読み取り専用セグメントに格納されているため、書き込むことはできません。これはスタックオーバーフロー保護ではなく、メモリ書き込み保護のみです(プログラムがそれ自体を書き換えることができる場合、これはセキュリティホールです)。
バスエラーの典型的な例の1つは、SPARC(少なくとも一部のSPARC、おそらくこれは変更されている)などの特定のアーキテクチャーで発生し、不整合なアクセスを行った場合です。例えば:
unsigned char data[6];
(unsigned int *) (data + 2) = 0xdeadf00d;
このスニペットは、32ビット整数値0xdeadf00d
を(ほとんどの場合)適切に配置されていないアドレスに書き込もうとし、この点で「ピッキー」なアーキテクチャでバスエラーを生成します。インテルのx86は道、によって、あるいないようなアーキテクチャ、それが(もっとゆっくり、それを実行するにもかかわらず)のアクセスを可能にします。
通常、非境界整列アクセスを意味します。
物理的に存在しないメモリにアクセスしようとすると、バスエラーも発生しますが、MMUを搭載したプロセッサとバグのないOSを使用している場合は、非バグがないため、このエラーは表示されません。 -プロセスのアドレス空間にマッピングされた既存のメモリ。
scanf
)。それは、OS X Mavericksにバグがあるということですか?バグのないOSでの動作は何でしょうか?
Mac OS Xでバスエラーが発生した理由は、スタックに約1Mbを割り当てようとしたためです。これは1つのスレッドでうまく機能しましたが、openMPを使用すると、Mac OS Xの非メインスレッドのスタックサイズが非常に制限されているため、これがバスエラーを引き起こします。
上記のすべての回答に同意します。BUSエラーに関する私の2セントは次のとおりです。
BUSエラーは、プログラムのコード内の命令から発生する必要はありません。これは、バイナリを実行しているときに発生し、実行中にバイナリが変更されます(ビルドによって上書きされたり、削除されたりするなど)。
これが原因かどうかの確認:これが原因かどうかを確認する簡単な方法は、同じバイナリの実行中のインスタンスを起動してビルドを実行することです。SIGBUS
ビルドが完了してバイナリ(両方のインスタンスが現在実行しているもの)を置き換えた直後に、実行中の両方のインスタンスがエラーでクラッシュしました。
根本的な理由: これは、OSがメモリページをスワップし、場合によってはバイナリが完全にメモリに読み込まれないことがあり、OSが同じバイナリから次のページをフェッチしようとしたが、最後からバイナリが変更されたためにこれらのクラッシュが発生するためですそれを読んで。
上記のblxtdの回答に加えて、プロセスが特定の「変数」のメモリにアクセスできない場合にもバスエラーが発生します。
for (j = 0; i < n; j++) {
for (i =0; i < m; i++) {
a[n+1][j] += a[i][j];
}
}
お知らせ「不注意の」使用法、変数「I」で「forループ初?これが、この場合のバスエラーの原因です。
ARMv7プロセッサで、最適化されていないときにセグメンテーション違反を発生させるコードを記述できるが、-O2(さらに最適化)でコンパイルするとバスエラーが発生するという難しい方法を見つけました。
Ubuntu 64ビットのGCC ARM gnueabihfクロスコンパイラを使用しています。
バスエラーを引き起こす典型的なバッファオーバーフローは、
{
char buf[255];
sprintf(buf,"%s:%s\n", ifname, message);
}
ここで、二重引用符( "")内の文字列のサイズがbufサイズより大きい場合、バスエラーが発生します。