GoogleTest EXPECT_DEATH не ловит дважды бесплатно()

#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() — это Неопределенное поведение. Это может привести к сбою, а может и нет, нет ничего, в чем можно быть уверенным при вызове UB

2. В общем, вы не можете полагаться на то, что двойное свободное вызовет сбой. Проходит ли тестовый случай, если вы удалите EXPECT_DEATH? Возможно, необходимо установить какой-то параметр распределителя памяти, чтобы увеличить вероятность сбоя с двойным освобождением

3. Программа завершит работу, если я дважды освобожу память, то есть, если я выполню функцию free() вне предложения EXPECT_DEATH (). Хотя double free() не определен, в этой комбинации архитектуры и компилятора его поведение является последовательным сбоем, и я ожидал бы, что это каким-то образом будет обнаружено платформой.

4. Как правило, действительно сложно проверить распределение памяти, выполняемое malloc() / free или new / delete . Вы также не знаете, какие методы фреймворка вызывают эти функции или операторы. Если вы используете GCC, рассмотрите возможность использования -wrap опции для перехвата вызовов. Остерегайтесь искажения имен в C , который является языком GoogleTest.