#c #googletest #free
Вопрос:
Используя платформу тестирования Google, я хочу иметь возможность определить, что программа выйдет из строя, если я случайно дважды освобожу() выделенную память. Я ожидал, что произойдет что-то следующее, чтобы поймать аварию:
TEST(DEATHTEST, InvalidFree) { ::testing::FLAGS_gtest_death_test_style = "threadsafe"; int *data = (int *)malloc(sizeof(int)); free(data); EXPECT_DEATH(free(data), ".*"); }
Если я действительно освобожу() память дважды за пределами тестовой среды, программа выйдет из строя. Однако тестовый случай завершается неудачно, сообщая:
Death test: free(data) Result: failed to die. Error msg: [ DEATH ] [ FAILED ] DEATHTEST.InvalidFree (3 ms)
Я также пытался:
EXPECT_EXIT(free(data), ::testing::KilledBySignal(SIGABRT), ".*");
и я пробовал использовать другие сигналы, такие как SIGSEGV.
Что я делаю не так? Неужели просто невозможно поймать такого рода аварию? (Я понимаю, что поведение двойного свободного не определено, но я ожидал бы, что сбой, тем не менее, должен быть обнаружен.)
Примечание: На самом деле я не хочу проверять, что двойной бесплатный сбой. Вместо этого я хочу убедиться, что функция освобождает некоторую выделенную память. Поскольку я не могу легко издеваться над функцией free (), вместо этого я подумал, что могу проверить, что попытка освободить память после выполнения функции косвенно проверит освобождение памяти функции.
Комментарии:
1. двойное
free()
— это Неопределенное поведение. Это может привести к сбою, а может и нет, нет ничего, в чем можно быть уверенным при вызове UB2. В общем, вы не можете полагаться на то, что двойное свободное вызовет сбой. Проходит ли тестовый случай, если вы удалите EXPECT_DEATH? Возможно, необходимо установить какой-то параметр распределителя памяти, чтобы увеличить вероятность сбоя с двойным освобождением
3. Программа завершит работу, если я дважды освобожу память, то есть, если я выполню функцию free() вне предложения EXPECT_DEATH (). Хотя double free() не определен, в этой комбинации архитектуры и компилятора его поведение является последовательным сбоем, и я ожидал бы, что это каким-то образом будет обнаружено платформой.
4. Как правило, действительно сложно проверить распределение памяти, выполняемое
malloc()
/free
илиnew
/delete
. Вы также не знаете, какие методы фреймворка вызывают эти функции или операторы. Если вы используете GCC, рассмотрите возможность использования-wrap
опции для перехвата вызовов. Остерегайтесь искажения имен в C , который является языком GoogleTest.