Warum führt eine Leseoperation in einer speicherabgebildeten Null-Byte-Datei zu SIGBUS?

8

Hier ist der Beispielcode, den ich geschrieben habe.

%Vor%

Wenn ich diesem Programm ein Nullbyte foo.txt gebe, endet es mit SIGBUS.

%Vor%

Wenn ich diesem Programm ein Byte foo.txt gebe, dann gibt es kein solches Problem.

%Vor%

mmap (2) erwähnt Folgendes:

  

Die Verwendung einer kartierten Region kann zu folgenden Signalen führen:

     

SIGSEGV Es wurde versucht, in eine Region schreibgeschützt zu schreiben.

     

SIGBUS Versuchte Zugriff auf einen Teil des Puffers, der nicht mit der Datei übereinstimmt (z. B. über das Ende der Datei hinaus, einschließlich des Falls, bei dem ein anderer Prozess die Datei abgeschnitten hat).

Wenn ich das richtig verstehe, sollte sogar der zweite Testfall (1-Byte-Datei) zu SIGBUS geführt haben, weil data[1] und data[2] versuchen, auf einen Teil des Puffers ( data ) zuzugreifen, der dies tut entspricht nicht der Datei.

Können Sie mir helfen zu verstehen, warum nur eine Null-Byte-Datei dazu führt, dass dieses Programm mit SIGBUS fehlschlägt?

    
Lone Learner 01.01.2017, 13:59
quelle

2 Antworten

5

Sie erhalten SIGBUS beim Zugriff über das Ende der letzten vollständig abgebildeten Seite, weil die POSIX-Standardzustände :

  

Die Funktion mmap() kann verwendet werden, um eine Speicherregion abzubilden, die größer ist als die aktuelle Größe des Objekts. Speicherzugriff innerhalb des Mappings, aber über das aktuelle Ende der zugrundeliegenden Objekte hinaus kann dazu führen, dass SIGBUS -Signale an den Prozess gesendet werden.

Bei einer Null-Byte-Datei ist die gesamte Seite, die Sie zugeordnet haben, "jenseits des aktuellen Endes des zugrunde liegenden Objekts". So erhalten Sie SIGBUS .

Sie erhalten KEIN SIGBUS , wenn Sie über die 4 kB-Seite hinausgehen, die Sie zugeordnet haben, da dies nicht in Ihrem Mapping enthalten ist. Sie erhalten kein SIGBUS , wenn Sie auf Ihr Mapping zugreifen, wenn Ihre Datei größer als 0 Byte ist, weil die gesamte Seite zugeordnet wird.

Aber Sie erhalten SIGBUS , wenn Sie zusätzliche Seiten über das Ende der Datei hinaus zugeordnet haben, z. B. Mapping zwei 4 kB Seiten für eine 1-Byte-Datei. Wenn Sie auf diese zweite 4kB-Seite zugreifen, erhalten Sie SIGBUS .

    
Andrew Henle 01.01.2017, 14:36
quelle
3

Eine 1-Byte-Datei führt nicht zum Absturz, weil mmap Speicher in Vielfachen der Seitengröße abbildet und den Rest null setzt. Von der Manpage:

  

Eine Datei wird in Vielfachen der Seitengröße abgebildet. Für eine Datei das ist          Nicht ein Vielfaches der Seitengröße, der verbleibende Speicherplatz wird auf Null gesetzt          zugeordnet und schreibt in diese Region nicht in die Datei geschrieben werden.          Der Effekt der Änderung der Größe der zugrunde liegenden Datei eines Mappings          auf den Seiten, die den hinzugefügten oder entfernten Regionen der Datei entsprechen          ist nicht spezifiziert.

    
ma_il 01.01.2017 14:08
quelle

Tags und Links