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?
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, dassSIGBUS
-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
.
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.