2010-01-15 15 views
15

Ich versuche sehr schwer, einen Busfehler zu bekommen.Wie bekomme ich einen "Busfehler"?

Ein Weg ist fehlausgerichteten Zugriff und ich habe versucht, die Beispiele gegeben here und here, aber kein Fehler für mich - die Programme ausführen, einfach gut.

Gibt es Situationen, die einen Busfehler verursachen?

+2

Welche Plattform und Hardware-Architektur verwenden Sie? –

+0

Es sollte beachtet werden, dass x86 standardmäßig keinen Busfehler hat, stattdessen wird es funktionieren, aber der Speicherzugriff ist nicht so performant wie ein ausgerichteter Lesevorgang. Auf der anderen Seite haben SPARC Bögen einen Busfehler. –

+1

Nein, siehe Michael Burrs Kommentare und meine Antwort. Selbst auf x86 können Sie einen Busfehler erhalten, indem Sie versuchen, auf Speicher zuzugreifen, der nicht existiert (im Gegensatz zu einem Segmentierungsfehler, der von einer Verletzung der Zugriffsrichtlinie herrührt). – ephemient

Antwort

12

Bus Fehler können nur auf Hardware-Plattformen aufgerufen werden, die:

  1. benötigen Zugriff ausgerichtet sind, und
  2. Sie für einen nicht ausgerichteten Zugriff, indem zwei ausgerichtete Zugriffe und kombiniert die Ergebnisse nicht kompensieren.

Sie haben wahrscheinlich keinen Zugang zu einem solchen System.

+0

gibt es einen Weg, um sicher zu sein? – Lazer

+0

@eSKay: Wenn Sie eine Intel-CPU verwenden, die heutzutage praktisch jeden Personal Computer bedeutet, erhalten Sie nie einen Busfehler von falsch ausgerichtetem Zugriff. Wenn Sie PowerPC, SPARC usw. verwenden, können Sie auf diese Weise einen Busfehler verursachen. –

+2

Haben Sie ein SPARC- oder MIPS-Gerät? –

0

Einfach, in den Speicher schreiben, das Ihnen nicht gehört:

int main() 
{ 
    char *bus_error = 0; 

    *bus_error = 'X'; 
} 

Instant-Bus-Fehler auf meinem PowerPC Mac [OS X 10.4, Dual 1GHz PPC7455 ist], die nicht unbedingt auf Ihrer Hardware und/oder Betriebssystem .

Es gibt sogar eine wikipedia article über Busfehler, einschließlich eines Programms, um einen zu machen.

+3

Auf moderner Hardware, die zu einem Segmentierungsfehler führt, nicht zu einem Busfehler. –

+1

Dies wurde auf meinem PowerPC Mac, ziemlich "modern" zusammengestellt. Aber der gleiche Code auf meinen zwei handlichen x86-Maschinen segfaults, du hast Recht. – Seth

+1

Das hängt auch von Ihrem Betriebssystem und Ihrer Konfiguration ab - wenn ich dies auf meinem PowerPC Mac unter Linux ausführe, bekomme ich einen SIGSEGV. OS X gibt SIGBUS in mehr Situationen als Linux; es ist nicht wie POSIX immer ein Signal oder das andere Mandat ... – ephemient

1

Beachten Sie auch, dass einige Betriebssysteme "Busfehler" für andere Fehler als falsch ausgerichteten Zugriff melden. Du hast in deiner Frage nicht erwähnt, was du eigentlich versucht hast zu erreichen. Vielleicht so versuchen:

int *x = 0; 
*x=1; 

der Wikipedia-Seite verknüpft erwähnt, dass der Zugang zu nicht vorhandenen Speicher kann auch zur Folge haben ein Bus-Fehler ist. Möglicherweise haben Sie mehr Glück beim Laden einer bekanntermaßen ungültigen Adresse in einen Zeiger und Dereferwcing.

-1

Busfehler treten auf, wenn Sie versuchen, auf Speicher zuzugreifen, der von Ihrem Computer nicht angesprochen werden kann. Zum Beispiel hat der Speicher Ihres Computers einen Adressbereich von 0x00 bis 0xFF, aber Sie versuchen, auf ein Speicherelement bei 0x0100 oder höher zuzugreifen.

In Wirklichkeit wird Ihr Computer einen viel größeren Bereich als 0x00 bis 0xFF haben.

Ihre ursprüngliche Post zu beantworten:

Tell me some situation which is sure to produce a bus error.

in Ihrem Code-Index in dem Speicher Art und Weise außerhalb des Bereichs der maximalen Speichergrenze. Ich weiß nicht ... verwenden Sie eine Art von riesigen Hex-Wert 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF indexiert in ein Zeichen * ...

+0

Ein "riesiger Hexadezimalwert" wie dieser wird überlaufen, wenn er in den Zeiger passt. Die meisten Betriebssysteme sollten ohnehin nicht zugreifbaren Speicher schützen, so dass Sie nur einen SIGSEGV statt eines Busfehlers treffen. –

15

Dies sollte zuverlässig zu einem SIGBUS auf einem POSIX-konformen System führen.

#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; 
} 

Von der Single Unix Specification, mmap:

References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

+0

Schöner Fund. Ich habe überprüft, dass dies einen Busfehler sowohl bei openSUSE 11.1 als auch bei Darwin 10.2.0 (d. H. Mac OS x 10.6.2) verursacht. –

+0

Ich weiß, das ist ein alter Thread, aber .. Kann jemand erklären, warum dies einen 'Busfehler' verursacht? Ich verstehe, dass der Bus-Fehler in der Zeile "* m = 0;" auftritt, aber ich sehe nicht, wie es mit der Erklärung des SIGBUS-Signals in dieser Antwort zitiert zitiert wird. – digawp

3

Wie andere erwähnt haben dies ist sehr plattformspezifisch.Auf dem ARM-System, mit dem ich arbeite (es gibt keinen virtuellen Speicher), gibt es große Teile des Adressraums, denen kein Speicher oder Peripheriegerät zugewiesen ist. Wenn ich eine dieser Adressen lese oder schreibe, bekomme ich einen Busfehler.

Sie können auch einen Busfehler erhalten, wenn tatsächlich ein Hardwareproblem am Bus vorliegt.

Wenn Sie auf einer Plattform mit virtuellem Speicher arbeiten, können Sie absichtlich keinen Busfehler mit Ihrem Programm generieren, es sei denn, es handelt sich um einen Gerätetreiber oder eine andere Kernelmodus-Software. Ein ungültiger Speicherzugriff würde wahrscheinlich vom Speichermanager als Zugriffsverletzung oder Ähnliches eingefangen werden (und es hat niemals eine Chance, den Bus zu treffen).

6

Probieren Sie etwas entlang der Linien von: (ich weiß, wahrscheinlich nicht die Antwort, die Sie wollen, aber es ist fast sicher, dass Sie einen „Bus-Fehler“ zu erhalten)

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

1

Wie wäre es damit ? ungetestet.

#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; 
    } 
3

auf Linux mit einem Intel-CPU dies versuchen:

int main(int argc, char **argv) 
{ 
# if defined i386 
    /* enable alignment check (AC) */ 
    asm("pushf; " 
    "orl $(1<<18), (%esp); " 
    "popf;"); 
# endif 

    char d[] = "12345678"; /* yep! - causes SIGBUS even on Linux-i386 */ 
    return 0; 
} 

der Trick hier ist die "Ausrichtung überprüfen" Bit in einen der CPUs "spezielle" Register zu setzen.

siehe auch: here

3

Ich bin sicher, dass Sie x86-Rechner verwendet werden müssen. X86-CPU erzeugt keinen Busfehler, es sei denn, ihr AC-Flag im EFALAGS-Register ist gesetzt.

diesen Code Versuchen:

#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; 
} 

über dieses Mehr kann http://orchistro.tistory.com/206

+0

Ich habe dieses Experiment auf meiner Maschine versucht und ich habe einen SIGBUS. Aber dann entfernte ich alle Zeilen mit Ausnahme der '__asm__' Zeile und der' return 0; 'und ich bekomme immer noch einen SIGBUS. Also muss ein anderer nicht ausgerichteter Zugriff stattfinden, vielleicht aus der CRT-Bibliothek. –

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'; 
    } 
} 

Bus-Fehler zu finden: 10 (core dumped)