Co oznacza komunikat „błąd magistrali” i czym się różni od segfault?
c
unix
segmentation-fault
bus-error
raldi
źródło
źródło
Odpowiedzi:
Błędy magistrali są obecnie rzadkie na x86 i występują, gdy procesor nie może nawet próbować uzyskać dostępu do pamięci, zwykle:
Błędy segmentacji występują podczas uzyskiwania dostępu do pamięci, która nie należy do twojego procesu, są bardzo częste i zwykle są wynikiem:
PS: Mówiąc ściślej, nie jest to manipulowanie samym wskaźnikiem, który spowoduje problemy, lecz dostęp do pamięci, na którą wskazuje (dereferencje).
źródło
/var/cache
była po prostu pełna askubuntu.com/a/915520/493379static_cast
zmodyfikowałavoid *
parametr do obiektu, który przechowuje wywołanie zwrotne (jeden atrybut wskazuje na obiekt, a drugi na metodę). Następnie wywoływane jest oddzwonienie. Jednak to, co zostało przekazane,void *
było czymś zupełnie innym, a zatem wywołanie metody spowodowało błąd magistrali.Segfault ma dostęp do pamięci, do której nie masz dostępu. Jest tylko do odczytu, nie masz uprawnień itp.
Błąd magistrali próbuje uzyskać dostęp do pamięci, której prawdopodobnie nie ma. Użyłeś adresu, który nie ma znaczenia dla systemu, lub niewłaściwego rodzaju adresu dla tej operacji.
źródło
mmap
przykład minimalnej wersji POSIX 7„Błąd magistrali” występuje, gdy jądro wysyła
SIGBUS
do procesu.Minimalny przykład, który go wytwarza, ponieważ
ftruncate
został zapomniany:Biegnij z:
Testowane w Ubuntu 14.04.
POSIX opisuje
SIGBUS
jako:Specyfikacja mmap mówi, że:
I
shm_open
mówi, że generuje obiekty o rozmiarze 0:Tak więc
*map = 0
dotykamy końca przydzielonego obiektu.Niezrównany dostęp do pamięci stosu w ARMv8 aarch64
Zostało to wspomniane w: Co to jest błąd magistrali? dla SPARC, ale tutaj podam bardziej powtarzalny przykład.
Wszystko czego potrzebujesz to wolnostojący program aarch64:
Ten program następnie podnosi SIGBUS na Ubuntu 18.04 aarch64, jądro Linuksa 4.15.0 na serwerze ThunderX2 .
Niestety nie mogę go odtworzyć w trybie użytkownika QEMU v4.0.0, nie jestem pewien dlaczego.
Błąd wydaje się być opcjonalny i kontrolowany przez pola
SCTLR_ELx.SA
iSCTLR_EL1.SA0
, streściłem pokrewne dokumenty nieco tutaj .źródło
Od: tutaj
źródło
Możesz także uzyskać SIGBUS, gdy z jakiegoś powodu strona kodowa nie może być stronicowana.
źródło
mmap
utworzenia pliku większego niż rozmiar/dev/shm
Konkretny przykład błędu magistrali, który właśnie napotkałem podczas programowania C w OS X:
W przypadku, gdy nie pamiętasz, dokumenty
strcat
dołączają drugi argument do pierwszego, zmieniając pierwszy argument (odwróć argumenty i działa dobrze). W Linuksie daje to błąd segmentacji (zgodnie z oczekiwaniami), ale w OS X daje błąd magistrali. Czemu? Naprawdę nie wiem.źródło
"foo"
jest przechowywany w segmencie pamięci tylko do odczytu, więc nie można do niego pisać. Nie byłaby to ochrona przed przepełnieniem stosu, tylko ochrona przed zapisem pamięci (jest to dziura w zabezpieczeniach, jeśli Twój program może sam przepisać).Klasyczne wystąpienie błędu magistrali występuje w niektórych architekturach, takich jak SPARC (przynajmniej niektóre SPARC, być może to zostało zmienione), kiedy ma się źle ustawiony dostęp. Na przykład:
Ten fragment próbuje zapisać 32-bitową wartość całkowitą
0xdeadf00d
na adres, który (najprawdopodobniej) nie jest właściwie wyrównany, i wygeneruje błąd magistrali na architekturach, które są „wybredne” pod tym względem. Intel x86, nawiasem mówiąc, nie jest taką architekturą, pozwoliłby na dostęp (choć należy go wykonać wolniej).źródło
Zależy to od systemu operacyjnego, procesora, kompilatora i ewentualnie innych czynników.
Ogólnie oznacza to, że magistrala procesora nie może wykonać polecenia lub wystąpił konflikt, ale może to oznaczać cały szereg rzeczy w zależności od środowiska i uruchomionego kodu.
-Adam
źródło
Zwykle oznacza to niezrównany dostęp.
Próba dostępu do pamięci, która nie jest fizycznie obecna, również dałaby błąd magistrali, ale nie zobaczysz tego, jeśli używasz procesora z MMU i systemu operacyjnego, który nie jest wadliwy, ponieważ nie będziesz mieć żadnego -istniejąca pamięć odwzorowana na przestrzeń adresową procesu.
źródło
scanf
). Czy to oznacza, że OS X Mavericks jest wadliwy? Jak wyglądałoby zachowanie systemu operacyjnego bez wad?Wystąpił błąd magistrali, gdy katalog główny był w 100%.
źródło
Przyczyną błędu magistrali w systemie Mac OS X było to, że próbowałem przydzielić około 1 Mb na stosie. Działa to dobrze w jednym wątku, ale podczas korzystania z openMP powoduje to błąd magistrali, ponieważ Mac OS X ma bardzo ograniczony rozmiar stosu dla wątków innych niż główne .
źródło
Zgadzam się ze wszystkimi powyższymi odpowiedziami. Oto moje 2 centy za błąd magistrali:
Błąd magistrali nie musi wynikać z instrukcji zawartych w kodzie programu. Może się to zdarzyć, gdy uruchomisz plik binarny, a podczas wykonywania plik binarny zostanie zmodyfikowany (nadpisany przez kompilację lub usunięty itp.).
Sprawdzanie, czy tak jest: Prostym sposobem sprawdzenia, czy to jest przyczyna, jest uruchomienie uruchomionych instancji tego samego pliku binarnego i uruchomienie kompilacji. Obie działające instancje uległyby awarii z
SIGBUS
błędem wkrótce po zakończeniu kompilacji i zastąpiły plik binarny (ten, który obecnie działają obie instancje)Zasadniczy powód: Dzieje się tak, ponieważ system operacyjny zamienia strony pamięci, aw niektórych przypadkach plik binarny może nie zostać całkowicie załadowany do pamięci, a awarie te występują, gdy system operacyjny próbuje pobrać następną stronę z tego samego pliku binarnego, ale plik binarny zmienił się od czasu ostatniego Przeczytaj to.
źródło
Aby dodać do odpowiedzi blxtd powyżej, błędy magistrali występują również wtedy, gdy proces nie może uzyskać dostępu do pamięci określonej „zmiennej” .
Czy zauważyłeś „ niezamierzone ” użycie zmiennej „i” w pierwszym „for loop”? To właśnie powoduje błąd magistrali w tym przypadku.
źródło
Właśnie dowiedziałem się na własnej skórze, że na procesorze ARMv7 możesz napisać kod, który daje błąd segmentacji, gdy nie jest zoptymalizowany, ale daje błąd magistrali po skompilowaniu z -O2 (zoptymalizuj więcej).
Korzystam z kompilatora krzyżowego GCC ARM gnueabihf z Ubuntu 64-bit.
źródło
Typowe przepełnienie bufora, które powoduje błąd magistrali,
Jeśli wielkość ciągu w podwójnych cudzysłowach („”) jest większa niż rozmiar buf, oznacza to błąd magistrali.
źródło