Как смоделировать ошибки выделения памяти? - PullRequest
2 голосов
/ 07 апреля 2010

Я хочу тщательно протестировать некоторые фрагменты кода на наличие утечек памяти.

На моей машине у меня 4 ГБ ОЗУ, поэтому маловероятно, что динамическое выделение памяти завершится неудачно Тем не менее, я хочу посмотреть на код, если не удастся выделить память, и посмотреть, достаточно ли силен механизм восстановления.

Что вы предлагаете? Как мне эмулировать среду с более низкими характеристиками памяти? Как мне издеваться над своими тестами?

EDIT : Я хочу, чтобы мои тесты были независимыми от кода. У меня есть только «доступ» для возврата значений для различных функций в библиотеке, которую я тестирую. Я не должен писать «тестовую логику» внутри кода, который я тестирую.

Ответы [ 6 ]

4 голосов
/ 07 апреля 2010

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

4 голосов
/ 07 апреля 2010

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

Тогда:

#define malloc(X) (myMalloc(X))
#define free(X) (myFree(X))
#define realloc(X, Y) (myRealloc(X, Y))
#define calloc(X, Y) (myCalloc(X, Y))
#define valloc(X) (myValloc(X))

Вы можете #define и #undef макросы, как вы хотите в вашем коде.

3 голосов
/ 07 апреля 2010

Если это система типа unix, то вы можете сделать то же самое, что и jemalloc. Реализуйте свой собственный malloc, скомпилируйте его как .so -library и запустите тест с LD_PRELOAD = yourmalloc.so

Вы можете встроить параметр, который позволит вам контролировать его работу:

void tester() {
     your_malloc_allow_allocation(1024*1024*4); // allow 4 more megs of allocation

     librarycall();
     // ... handle errors..

     your_malloc_reset_limits(); // drop limits
}
1 голос
/ 07 апреля 2010

Когда мне пришлось это сделать, я сделал небольшую программу, которая быстро израсходовала всю память. Примерно так:

// Beware, brain-compiled code ahead: 
#include <stdlib.h>

bool alloc(size_t n)
{
    return NULL != malloc(n);
}

int main()
{
    size_t n = 1;
    for(;;) {
        while( alloc(n) )
            n*=2;
        do
            n/=2;
        while( !alloc(n) );
    }
}

Мой опыт работы с линейкой NT для Windows заключался в том, что, хотя операционная система отличная, почти все остальное рухнуло на меня, включая отладчик. Не интересно работать таким образом.

1 голос
/ 07 апреля 2010

отключите своп, затем в начале вашего приложения выполните while(malloc(1000000));

Это оставит среду с менее чем 1 МБ свободной памяти для запуска остальной части вашего приложения. Настройте значение для других результатов.

1 голос
/ 07 апреля 2010

введите * (символ *) 0; когда вы хотите, чтобы ваш код потерпел неудачу или сохранил его в выделенной переменной

(очевидно, он должен быть активирован / деактивирован некоторым #define, установленным makefile)

Идея состоит в том, чтобы точно контролировать, какой malloc вы хотите потерпеть неудачу. Я использовал предыдущий трюк, чтобы убедиться в поведении написанной мною программы, если когда-либо случится ошибка. Мне удалось проверить, что исключение было перехвачено и что не было утечки памяти с уже выделенным объектом.

Вы также можете добавить какой-то счетчик, чтобы ваш alloc возвращал 0 только через некоторое время и проверить, что ваш код корректно обрабатывает этот случай (и, например, правильно освобождает части того, что ваша программа решает уничтожить, чтобы справиться с нехваткой памяти). ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...