Как симулировать ошибки выделения памяти - PullRequest
22 голосов
/ 20 сентября 2008

Приложение My C использует третьи библиотеки, которые осуществляют собственное управление памятью. Для того, чтобы быть устойчивым, в моем приложении есть код для устранения сбоев библиотечных функций из-за недостатка свободной памяти.

Я хотел бы протестировать этот код, и для этого мне нужно смоделировать сбои из-за нехватки памяти.

Какие инструменты рекомендуются для этого? Моя среда Linux / gcc.

Ответы [ 11 ]

22 голосов
/ 20 сентября 2008

Вы можете использовать ulimit, чтобы ограничить количество ресурсов, которые может использовать пользователь, включая память. Таким образом, вы создаете тестового пользователя, ограничиваете его использование памяти чем-то, достаточным для запуска вашей программы, и наблюдаете, как он умирает

Пример:

ulimit -m 64

Устанавливает ограничение памяти в 64 КБ.

13 голосов
/ 20 сентября 2008

Создайте свою собственную оболочку malloc, которая будет случайным образом возвращать ноль вместо действительного указателя. Ну или что не получается последовательно, если вы хотите провести модульное тестирование.

7 голосов
/ 23 сентября 2008

В операционных системах, которые перегружают память (например, Linux или Windows), просто невозможно обрабатывать ошибки нехватки памяти. malloc может вернуть действительный указатель, и позже, когда вы попытаетесь разыменовать его, ваша операционная система может определить, что у вас недостаточно памяти и завершить процесс.

http://www.reddit.com/comments/60vys/how_not_to_write_a_shared_library/ хорошая статья по этому поводу.

5 голосов
/ 20 сентября 2008

Вместо этого вы можете написать свою собственную макетную библиотеку с тем же интерфейсом, что и у сторонней библиотеки. Вы также можете использовать LD_PRELOAD для переопределения выбранных функций сторонней библиотеки.

3 голосов
/ 20 сентября 2008

Я могу дать конкретную версию для Linux (может быть, POSIX): __malloc_hook, __realloc_hook, __free_hook. Они объявлены в malloc.h.

РЕДАКТИРОВАТЬ: небольшая проработка: это указатели на функции (точную декларацию см. На malloc.h и их man-странице), но будьте осторожны: это не совсем стандарты, а только расширения GNU. Так что, если переносимость является проблемой, не используйте это.

Чуть менее зависимым от платформы решением может быть объявление макроса malloc. Если вы тестируете, это вызывает хук и настоящий malloc.

memhook.h:

#define malloc(s)    (my_malloc(s))

memhook.c:

#include "memhook.h"
#undef malloc
#include <stdlib.h>

и т.д.

Вы можете использовать это для обнаружения утечек, случайного сбоя при распределении и т. Д.

1 голос
/ 20 сентября 2008

Кроме того, вы должны использовать Valgrind , чтобы протестировать все это и получить реальные полезные отчеты о поведении памяти вашей программы

0 голосов
/ 05 ноября 2018

Вы можете настроить определение в заголовочном файле так, чтобы оно возвращало NULL при каждом использовании malloc:

Обычно malloc защищается следующим образом:

if ((int *x = malloc(sizeof(int))) == 0)
   return NULL;

Таким образом, вы используете определение для принудительного возврата NULL; Пример псевдокода:

# define if(malloc(x))   if(1)

И проверьте, есть ли у вас ошибка

0 голосов
/ 26 мая 2010

Посмотрите на способ, которым sqlite3 делает это . Они выполняют всестороннее модульное тестирование, в том числе тестирование вне памяти.

Вы также можете посмотреть их страницу на malloc , в частности Раздел 4.0 .

0 голосов
/ 19 октября 2008

Возможно, вы захотите взглянуть на некоторые сайты, ориентированные на восстановление, такие как Беркли / Стэнфордская группа ROC . Я слышал, как некоторые из этих людей говорили раньше, и они используют код для случайного внедрения ошибок во время выполнения Си. Внизу их страницы есть ссылка на инструмент FIT.

0 голосов
/ 22 сентября 2008

(в качестве дополнения к некоторым из предыдущих ответов)

Оформление "Electric Fence" для примера библиотеки перехвата malloc, которую вы можете использовать со своим исполняемым файлом (например, с помощью трюка LD_PRELOAD)

После того, как вы перехватили malloc, вы можете использовать все, что захотите, чтобы вызвать сбои. Случайно вызванный сбой был бы хорошим стресс-тестом для различных частей системы. Вы также можете изменить вероятность сбоя в зависимости от объема запрошенной памяти.

Кстати, ваша идея интересна, и я бы хотел кое-что сделать с ее кодом ...

...