Frage

Gibt es eine Funktion analog zu IsBadReadPtr in Unix? Wenigstens einige Funktionalitäten von IsBadReadPtr? Ich möchte ein Verfahren schreiben, wenn etwas Schlimmes zu einem Prozess geschieht (wie SIGSEGV) reagieren würde und einige Informationen erholen. Aber ich möchte die Zeiger überprüfen, um sicherzustellen, dass die Daten nicht beschädigt ist und sehen, ob sie sicher zugegriffen werden kann. Andernfalls wird der Crash-Abwicklungsvorgang selbst wird abstürzen, so nutzlos werden.

Irgendwelche Vorschläge?

War es hilfreich?

Lösung

Der üblicher Weg, dies auf POSIX-Systemen zu tun, ist den write() Systemaufruf zu verwenden. 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 zu verwenden, um diese auf Linux, weil sie von jedem Benutzer geschrieben werden können und tatsächlich versuchen, den Speicher zu lesen gegeben. Auf OSes ohne /dev/random oder wo es nicht beschreibbar ist, versuchen /dev/null). Eine weitere Alternative wäre ein anonymes Rohr sein, aber wenn Sie einen großen Bereich testen mögen, müssen Sie müssen regelmäßig das Lese Ende des Rohres löschen.

Andere Tipps

Man kann nie wissen „ob ein Zeiger sicher zugegriffen werden kann“, unter Windows oder Unix. Aber für einige ähnliche Informationen auf einigen Unix-Plattformen Besuche cat /proc/self/maps.

Wie können Sie es tun?

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

Um dies zu tun, zuerst setzen Sie ein sigsetjmp und einen SIGSEGV Signal-Handler auf. Versuchen Sie dann den Zeiger zu verwenden. Wenn es ein schlechter Zeiger dann die SIGSEGV Handler genannt wurde, und Sie können in Sicherheit springen und den Fehler an den Benutzer melden.

Ich lief in das gleiche Problem versucht, ein ‚Pixel‘ lesen von einem Framebuffer während Ubuntu innerhalb einer VirtualBox läuft. Es schien kein sicherer Weg, um Zugang zu überprüfen, ohne abzuzustürzen oder acutally gdb hängen. Der Vorschlag von StasM deutete mich gegenüber zu folgenden Arbeits ‚lokale‘ Lösung mit Gabel.

void *some_address;
int pid = fork();
if (pid== 0)
{
    someaddress[0] = some_address[0];
    _exit(123);
}
bool access_ok = true;
int status;
int result = waitpid(pid, &status, 0);
if (result == -1 || WIFEXITED(status) == 0 || WEXITSTATUS(status) != 123)
{
    access_ok = false;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top