Как сделать динамические c выделения для сбоя запуска программы - PullRequest
1 голос
/ 06 февраля 2020

У меня есть программа C, которая использует malloc (это также может быть C ++ с new). Я хотел бы протестировать свою программу и смоделировать сценарий «нехватка памяти».

Я бы настоятельно предпочел бы запускать мою программу из среды оболочки bash или sh без изменения кода ядра.

Как сделать так, чтобы динамическое c выделение памяти не выполнялось при запуске программы?


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

$ ulimit -d 50
$ ./program_which_heap_allocates
./program_which_heap_allocates: error while loading shared libraries: libc.so.6: cannot map zero-fill pages
$ ulimit -d 51
bash: ulimit: data seg size: cannot modify limit: Operation not permitted

У меня проблемы с запуском программы таким образом, что может происходить динамическое связывание c (например, stdlib), но не выделения из моей программы.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Если вы находитесь под Linux и используете glib c, тогда есть крючки для Mallo c. Хуки позволяют вам перехватывать вызовы к mallo c и делать их случайными сбоями.

Ваш набор тестов может использовать переменную окружения, чтобы сообщить коду для вставки перехватчик mallo c и какой вызов mallo c потерпеть неудачу. Например, если вы установите FOOBAR_FAIL_MALLOC = 10, то ваш хук mallo c будет вести обратный отсчет и позволить 10-му использованию mallo c вернуть 0.

FOOBAR_FAIL_MALLOC = 0 может просто сообщать о количестве malloc в тестовом примере. Затем вы бы запустили тест один раз с FOOBAR_FAIL_MALLOC = 0 и зафиксировали количество задействованных malloc. Затем повторите для FOOBAR_FAIL_MALLOC = от 1 до N, чтобы протестировать каждый бит mallo c.

Если после сбоя mallo c у вас не будет больше malloc. Затем вы должны подумать о чем-то более сложном, чтобы указать, какие mallocs должны давать сбой.

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

Примечание: новый C ++ должен также нагревать mallo c hook

1 голос
/ 06 февраля 2020

Ваша тестовая программа может включать тестируемый c и использовать #define для переопределения вызовов на malloc.

Например:

prog. c:

#include <stdio.h>
#include <stdlib.h> 

void *foo(int x)
{
    return malloc(x);
}

тест. c:

#include <stdio.h>
#include <stdlib.h>

static char buf[100];
static int malloc_fail;

void *test_malloc(size_t n)
{
    if (malloc_fail) {
        return NULL;
    } else {
        return buf;
    }
}

#define malloc(x) test_malloc(x)
#include "prog.c"
#undef malloc

int main()
{
    void *p;
    malloc_fail=0;
    p = foo(5);
    printf("buf=%p, p=%p\n", (void *)buf, p);   // prints same value both times
    malloc_fail=1;
    p = foo(4);
    if (p) {
        printf("buf=%p, p=%p\n", (void *)buf, p);
    } else {
        printf("p is NULL\n");     // this prints
    }

    return 0;
}
...