2012-10-15 5 views

Antwort

-1

Nicht auf eine Datei zugreifen, die nicht verfügbar ist. Überprüfen Sie, ob die Datei noch vorhanden ist, oder verwenden Sie eine Datei, die nicht deaktiviert werden kann.

+4

Ich denke nicht, dass das wegen möglicher Rennbedingungen sehr hilfreich ist. Würde es helfen, 'SIGBUS' um den Code herum zu erwarten, der auf die gemappte Region zugreift? Oder etwas ähnliches? –

+1

Nein. 'SIGBUS' ist nicht unbedingt wiederherstellbar, obwohl einige Implementierungen den fehlerhaften Befehl nach der Rückkehr vom Handler erneut versuchen. –

+0

@SimonRichter Sie müssen den fehlerhaften Befehl nicht erneut versuchen, Sie müssen lediglich feststellen, dass Sie nicht mit einem Lese-/Schreibvorgang fortfahren können. Danach beenden Sie die Versuche, auf den Bereich zuzugreifen und mit einer Fehleranzeige zum Aufrufer zurückzukehren. Vielleicht wäre 'setjmp()'/'longjmp()' in der Lage, die wiederholte Ausführung der fehlerhaften Anweisung zu vermeiden. –

2

Am einfachsten ist es, einen Signal-Handler einzurichten, der auf Zugriffe auf Speicherplätze prüft, die mmap ed-Adressen entsprechen.

würden Sie die sigaction Form von Signal-Handler verwenden, anstatt den einfacheren signal Handler als sigaction Handler Informationen im struct __siginfo * Parameter entsprechend der Adresse des Empfangssignals. Dies kann überprüft werden, um festzustellen, ob es sich innerhalb des Adressbereichs der mmap Ed-Datei befindet.

mmap ist großartig, wenn Sie nicht mit den Komplikationen des Pufferlesens/Schreibens von Daten umgehen wollen, aber Sie bekommen nur eine Form von Fehler (ein Signal) wegen etwas schief geht. mit dem read/write Mechanismus, können Sie die errno und ermitteln, was passiert ist. Es ist sehr viel eine Entwicklerwahl in diesem Fall.

zu einer Stelle zu springen, nachdem das Signal dann müssen Empfangen Sie Nutzung des setjmp und longjmp/siglongjmp machen - sehen einige Verwendung dieser in this question

6

Zunächst einmal, ich möchte sollte dies sagen, als gutes Argument dienen mmap nicht unnötig als "optimiertes Lesen" oder ähnliches zu verwenden. Abgesehen von der Entfernung von Geräten können Probleme wie das Abschneiden von Dateien durch andere Prozesse zu fehlerhaften Zugriffen mit SIGBUS führen. Wenn Sie wirklich mmap verwenden müssen, könnten Sie einen Signalhandler für SIGBUS installieren. Ihre Aufgabe sollte grundsätzlich sein:

  1. einen globalen Set (oder Thread-local, wenn Ihr Programm ist multi-threaded) Flag, das ein SIGBUS aufgetreten, so dass die Verwerfungen Code kann bewusst sein.
  2. Rufen Sie mmap mit MAP_FIXED auf, um eine neue anonyme Seite über die fehlerhafte Seite zu mappen. Optional füllen Sie sie mit Daten aus, die vom Code, der auf die Karte zugreift, als fehlerhaft erkannt werden; Dies könnte Schritt 1 unnötig machen.

Ein alternativer Ansatz wäre ein globaler (oder Thread-local) jmp_buf vor dem Zugriff auf die Karte zu setzen sein, und haben einfach die Signal-Handler longjmp nennen.

Beachten Sie, dass weder mmap noch longjmp Asynchron-Signal-sicher ist, aber die SIGBUS in Frage ist nicht ein asynchrones Signal (obwohl es vielleicht ein in Betracht gezogen werden sollte, wenn die Verwerfungen Zugang in einer nicht-Asynchron-Signal-Safe-Bibliothek passierte Funktion wie sscanf). Solange es Ihr eigener Code ist und keine Bibliotheksfunktionen, Zugriff auf die Karte, sollten Sie mit beiden sicher sein. Und mmap ist in den meisten/allen Implementierungen der realen Welt async-signalsicher, so dass Sie mit der ersten Lösung in der Praxis einverstanden sein sollten, auch wenn sie nicht formal korrekt ist.

+2

Würde es so ausdrücken: es gibt mehr zu "mmap" als das Auge auffängt - weil Fehlerbehandlung viel komplexer ist als für traditionelle I/O. Das ist nicht unbedingt ein Grund gegen _mmmap' zu sein ... sei dir nur der Geister bewusst, die du beschwörst ;-) –

+0

Und achte darauf, dass sie nicht aus deiner Nase fliegen .. :-) –

-1

Sie können eine Benachrichtigung über jede Änderung an Datei (en), dir (s) mit http://linux.die.net/man/7/inotify erhalten. können Sie die Verwendung von IN_DELETE in Betracht ziehen.

+3

Werden diese Benachrichtigungen so unmittelbar angezeigt? wie Seitenfehler, die das OP versucht zu zügeln? Wenn nicht, nicht stören. –

+0

Es scheint, dass Sie 'read()' aufrufen müssen, um herauszufinden, ob es irgendwelche Änderungen gegeben hat, aber die Änderungen können zwischen 'read()' nichts von Interesse und dem folgenden Speicherzugriff zurückgeben. Es ist eine Wettlaufbedingung. Außerdem kann die Ereigniswarteschlange überlaufen. Also, das ist keine Lösung. –