Аналог IsBadReadPtr в Unix - PullRequest
       26

Аналог IsBadReadPtr в Unix

1 голос
/ 06 января 2011

Есть ли в Unix функция, аналогичная IsBadReadPtr ?По крайней мере, некоторые функциональные возможности IsBadReadPtr?Я хочу написать процедуру, которая будет реагировать, если с процессом происходит что-то плохое (например, SIGSEGV), и восстанавливать некоторую информацию.Но я хочу проверить указатели, чтобы убедиться, что данные не повреждены, и посмотреть, можно ли получить к ним безопасный доступ.В противном случае сама процедура обработки сбоев завершится сбоем и станет бесполезной.

Есть предложения?

Ответы [ 4 ]

7 голосов
/ 06 января 2011

Обычный способ сделать это в системах POSIX - использовать системный вызов write(). Он вернет EFAULT в errno, а не вызовет сигнал, если память не может быть прочитана:

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

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

(/dev/random - это хорошее устройство для использования в Linux, поскольку оно может быть записано любым пользователем и фактически попытается прочитать предоставленную память. В ОС без /dev/random или там, где оно не доступно для записи, попробуйте /dev/null). Другой альтернативой может быть анонимный канал, но если вы хотите протестировать большой регион, вам нужно регулярно очищать конец чтения канала.

1 голос
/ 06 января 2011

Вы никогда не сможете сказать, «можно ли получить безопасный доступ к указателю», в Windows или в Unix. Но для некоторой подобной информации на некоторых платформах Unix, проверьте cat /proc/self/maps.

0 голосов
/ 29 мая 2019

Я столкнулся с той же проблемой, пытаясь прочитать «пиксель» из кадрового буфера при запуске Ubuntu из виртуальной коробки.Казалось, не было безопасного способа проверить доступ без сбоя или зависания GDB.Предложение, сделанное StasM, подсказало мне, что нужно следовать рабочему «локальному» решению с использованием fork.

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;
}
0 голосов
/ 06 января 2011

Как это сделать?

Вы пытаетесь это сделать, а затем обрабатываете ошибку.

Для этого сначала вы устанавливаете sigsetjmp и обработчик сигнала SIGSEGV.Затем попытайтесь использовать указатель.Если это был неверный указатель, вызывается обработчик SIGSEGV, и вы можете перейти к безопасности и сообщить об ошибке пользователю.

...