17

バスエラーを発生させるために一生懸命努力しています。

1 つの方法はアクセスの不整合であり、ここここに示されている例を試しましたが、エラーは発生しませんでした。プログラムは問題なく実行されます。

確実にバスエラーが発生する状況はありますか?

4

12 に答える 12

20

SIGBUSこれにより、POSIX準拠のシステムで確実に結果が得られるはずです。

#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
int main() {
    FILE *f = tmpfile();
    int *m = mmap(0, 4, PROT_WRITE, MAP_PRIVATE, fileno(f), 0);
    *m = 0;
    return 0;
}

Single Unix 仕様から、mmap :

paから始まり、オブジェクトの末尾に続くlenバイトにわたって続くアドレス範囲内のページ全体への参照は、SIGBUS シグナルの配信をもたらすものとします。

于 2010-01-15T06:10:23.130 に答える
11

バス エラーは、次のハードウェア プラットフォームでのみ呼び出すことができます。

  1. アラインされたアクセスを要求し、
  2. 2 つのアライメントされたアクセスを実行し、結果を結合することによって、アライメントされていないアクセスを補正しないでください。

おそらく、そのようなシステムにアクセスすることはできません。

于 2010-01-15T04:09:34.010 に答える
7

次の行に沿って何かを試してください。

#include <signal.h>
int main(void)
{
    raise(SIGBUS);
    return 0;
}

(おそらく、あなたが望む答えではないでしょうが、「バスエラー」が発生することはほぼ確実です!)

于 2010-01-15T06:44:27.103 に答える
3

他の人が言及したように、これは非常にプラットフォーム固有です。私が使用している ARM システム (仮想メモリを持たない) では、メモリや周辺機器が割り当てられていないアドレス空間の大部分があります。これらのアドレスの 1 つを読み書きすると、バス エラーが発生します。

バス上に実際にハードウェアの問題がある場合にも、バス エラーが発生する可能性があります。

仮想メモリを備えたプラットフォームで実行している場合、デバイス ドライバーまたは他のカーネル モード ソフトウェアでない限り、プログラムでバス エラーを意図的に生成できない可能性があります。無効なメモリ アクセスは、メモリ マネージャによってアクセス違反または同様のものとしてトラップされる可能性があります (バスにヒットする機会さえありません)。

于 2010-01-15T06:20:47.893 に答える
3

x86 マシンを使用しているに違いありません。X86 CPU は、EFALAGS レジスタの AC フラグが設定されていない限り、バス エラーを生成しません。

このコードを試してください:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char *p;

    __asm__("pushf\n"
            "orl $0x40000, (%rsp)\n"
            "popf");

    /* 
     * malloc() always provides aligned memory.
     * Do not use stack variable like a[9], depending on the compiler you use,
     * a may not be aligned properly.
     */
    p = malloc(sizeof(int) + 1);
    memset(p, 0, sizeof(int) + 1);

    /* making p unaligned */
    p++;

    printf("%d\n", *(int *)p);

    return 0;
}

詳細については、http://orchistro.tistory.com/206を参照してください。

于 2011-12-07T09:10:07.500 に答える
1

これはどう?テストされていません。

  #include<stdio.h>

    typedef struct
    {
    int a;
    int b;
    } busErr;

    int main()
    {
    busErr err;
    char * cPtr;
    int *iPtr;
    cPtr = (char *)&err;
    cPtr++;
    iPtr = (int *)cPtr;
    *iPtr = 10;
    } 
于 2010-01-15T07:24:23.607 に答える
1

また、一部のオペレーティング システムでは、ミスアライン アクセス以外のエラーに対して「バス エラー」が報告されることにも注意してください。あなたは質問で、実際に達成しようとしていたことについて言及していませんでした。たぶん次のようにしてみてください:

int *x = 0;
*x=1;

あなたがリンクしたウィキペディアのページには、存在しないメモリへのアクセスもバスエラーになる可能性があると書かれています。既知の無効なアドレスをポインターにロードし、それを参照解除することで、運が良くなる可能性があります。

于 2010-01-15T05:53:52.337 に答える
1
int main(int argc, char **argv)
{
    char *bus_error = new char[1];
    for (int i=0; i<1000000000;i++) {
        bus_error += 0xFFFFFFFFFFFFFFF;
    *(bus_error + 0xFFFFFFFFFFFFFF) = 'X';
    }
}

バス エラー: 10 (コア ダンプ)

于 2013-03-22T14:39:51.377 に答える
0

簡単に、あなたのものではないメモリに書き込みます:

int main()
{
    char *bus_error = 0;

    *bus_error = 'X';
}

私の PowerPC Mac [OS X 10.4、デュアル 1GHz PPC7455's] でインスタント バス エラーが発生しましたが、ハードウェアやオペレーティング システムで発生するとは限りません。

バス エラーに関するウィキペディアの記事もあり、バス エラーを作成するプログラムも含まれています。

于 2010-01-15T04:21:48.397 に答える
-1

コンピュータがアドレス指定できないメモリにアクセスしようとすると、バス エラーが発生します。たとえば、コンピュータのメモリのアドレス範囲が 0x00 ~ 0xFF であるにもかかわらず、0x0100 以上のメモリ要素にアクセスしようとしたとします。

実際には、コンピュータの範囲は 0x00 から 0xFF よりもはるかに大きくなります。

元の投稿に回答するには:

確実にバスエラーが発生する状況を教えてください。

あなたのコードでは、最大メモリ制限の範囲外の方法でメモリにインデックスを付けます。私は知りません... char *にインデックス化されたある種の巨大な16進値0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFを使用します...

于 2010-01-15T06:01:51.730 に答える