2011-01-06 20 views
1

Gibt es eine Funktion analog zu IsBadReadPtr in Unix? Zumindest einige Funktionalitäten von IsBadReadPtr? Ich möchte eine Prozedur schreiben, die reagieren würde, wenn etwas mit einem Prozess passiert (wie SIGSEGV) und einige Informationen wiederherstellen. Aber ich möchte die Zeiger überprüfen, um sicherzustellen, dass die Daten nicht beschädigt sind und sehen, ob sie sicher zugegriffen werden können. Andernfalls stürzt die Crash-Prozedur selbst ab und wird dadurch unbrauchbar.IsBadReadPtr analog unter Unix

Irgendwelche Vorschläge?

+1

[Verwenden Sie nicht IsBad * Ptr.] (Http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx) – ephemient

Antwort

7

Die übliche Vorgehensweise für POSIX-Systeme ist die Verwendung des Systemaufrufs write(). Es wird wieder EFAULT in errno eher als ein Signal erhöht, wenn der Speicher nicht gelesen werden kann:

int nullfd = open("/dev/random", O_WRONLY); 

if (write(nullfd, pointer, size) < 0) 
{ 
    /* Not OK */ 
} 
close(nullfd); 

(/dev/random ist ein gutes Gerät für diesen unter Linux zu verwenden, weil sie von jedem Benutzer geschrieben werden können und tatsächlich versuchen Um den angegebenen Speicher zu lesen, versuchen Sie auf Betriebssystemen ohne /dev/random oder wo es nicht beschreibbar ist, /dev/null). Eine andere Alternative wäre eine anonyme Pipe, aber wenn Sie eine große Region testen möchten, müssen Sie regelmäßig das Leseende der Pipe löschen.

+0

Diese Lösung funktioniert nicht unter Linux 3.8.7 ... write() liefert IMMER Erfolg, wenn 'fd'/dev/null ist, auch wenn 'Zeiger' NULL ist. – etherice

+0

Unter Linux können Sie '/ dev/random' verwenden - ich habe die Antwort aktualisiert. – caf

+0

Ist es eine POSIX-Sache oder nur eine Linux-Sache für/dev/random write(), um den Entropie-Pool zu modifizieren? Wenn es aus irgendeinem Grund oder auf irgendeiner Plattform keinen Effekt hat, könnte der Kernel wählen, den Schreib-Op zu überspringen und den Erfolg sofort zurückzugeben, wie es mit/dev/null als Optimierung geschieht. Ohne diese Garantien wäre ich immer noch nervös wegen dieser Lösung. – etherice

1

Sie können niemals sagen "ob ein Zeiger sicher zugegriffen werden kann", unter Windows oder unter Unix. Aber für einige ähnliche Informationen auf einigen Unix-Plattformen, überprüfen Sie cat /proc/self/maps.

+1

Wenn ich unter gdb laufen, kann ich anzeigen Ein Speicherort und gdb würde entweder etwas anzeigen oder mir sagen "Kann nicht auf Speicher bei Adresse blah-blah" zugreifen. So weiß es, ob ich auf Adresse blah-bla zugreifen kann oder nicht - ich frage mich, wie ich das selbe aus meinem Programm machen könnte. – StasM

+0

@StasM: gdb macht gute Vermutungen. Außerdem greift es über * ptrace pokes auf * einen anderen * Prozess zu, also ist es in Ordnung, wenn es abstürzt. – ephemient

0

Wie können Sie es tun?

Sie versuchen, es zu tun und dann den Fehler zu behandeln.

Dazu richten Sie zunächst einen sigsetjmp- und einen SIGSEGV-Signalhandler ein. Versuchen Sie dann, den Zeiger zu verwenden. Wenn es ein schlechter Zeiger war, wird der SIGSEGV-Handler aufgerufen, und Sie können in Sicherheit springen und den Fehler dem Benutzer melden.

+0

Wenn ich versuche, es innerhalb SIGSEGV-Handler zu tun, wird es irgendwie komplex ... Kann auch SIGBUS sein. – StasM

+0

Verwenden Sie signalfd(). Es ist einfacher mit und Thread-sicher zu arbeiten. – asdf