Используйте signalfd (). С ним легче работать и он безопасен для потоков.

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

Какие-либо предложения?

 ephemient06 янв. 2011 г., 06:03

Ответы на вопрос(3)

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

 ephemient06 янв. 2011 г., 06:05
@StasM: GDB делает хорошие догадки. Также это доступ к памяти веще один процесс через ptrace pokes, так что все нормально, если он вылетает.
 StasM06 янв. 2011 г., 05:43
Если я запускаю под GDB, я могу отобразить место в памяти, и GDB будет либо отображать что-то или сказать мне"Cannot access memory at address blah-blah", Так что он знает, могу ли я получить доступ к адресу, бла-бла, - интересно, как я мог бы сделать то же самое из своей программы.

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

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

 asdf06 июл. 2011 г., 11:25
Используйте signalfd (). С ним легче работать и он безопасен для потоков.
 StasM06 янв. 2011 г., 06:21
Если я попытаюсь сделать это в обработчике SIGSEGV, он станет довольно сложным ... Также может быть SIGBUS.
Решение Вопроса

Обычный способ сделать это в системах 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). Другой альтернативой может быть анонимный канал, но если вы хотите протестировать большой регион, вам необходимо регулярно очищать конец чтения канала.

 caf21 апр. 2013 г., 02:03
В Linux вы можете использовать/dev/random - Я обновил ответ.
 etherice24 апр. 2013 г., 02:12
Это вещь POSIX или просто Linux для / dev / random write () для изменения пула энтропии? Если по какой-либо причине или на какой-либо платформе это не имеет никакого эффекта, тогда ядро ​​может решить пропустить операцию записи и немедленно вернуть успех, как это происходит с / dev / null в качестве оптимизации. Без таких гарантий я бы все еще нервничал из-за этого решения.
 caf24 апр. 2013 г., 03:44
Я не уверен что/dev/random Сам находится в POSIX. Метод объекта с разделяемой памятью также может быть хорошей идеей, но учтите, что POSIX оставляет эффектwrite() (а такжеlseek()) на объекте общей памяти "не указано". Я подозреваю, что самое портативное решение - этоpipe() дескриптор файла, но для этого требуется регулярное чтение или закрытие / воссоздание канала.
 etherice24 апр. 2013 г., 02:20
Кроме того, это может быть медленной записью в / dev / random, если он изменяет пул энтропии. В итоге я использовал объект общей памяти POSIX через shm_open (). Чтобы контролировать размер файла / объекта, я делаю lseek (shm_fd, 0, SEEK_SET) всякий раз, когда приблизительный размер превышает некоторый порог. Это делается (наряду с некоторыми другими оптимизациями), чтобы амортизированные накладные расходы были ограничены одним системным вызовом на вызов isMemoryBlockReadable (void *, size_t).
 etherice20 апр. 2013 г., 20:24
Это решение не работает в Linux 3.8.7 ... write () ВСЕГДА возвращает успех, если «fd» равен / dev / null, даже если «указатель» равен NULL.

Ваш ответ на вопрос