Как я могу определить, запущена ли программа из valgrind?

Есть ли способ определить во время выполнения, что исполняемый файл запускается из valgrind? У меня есть набор модульных тестов C++, и один из них ожидает, что std::vector::reserve выбросит std::bad_alloc. Когда я запускаю это под valgrind, он полностью выходит из строя, не позволяя мне тестировать как утечки памяти (с использованием valgrind), так и поведение (ожидая возникновения исключения).

Вот минимальный пример, который это воспроизводит:

#include <vector>
int main()
{
    size_t uint_max = static_cast<size_t>(-1);
    std::vector<char> v;
    v.reserve(uint_max);
}

Запустив valgrind, я получаю следующий результат:

Warning: silly arg (-1) to __builtin_new()
new/new[] failed and should throw an exception, but Valgrind
   cannot throw exceptions and so is aborting instead.  Sorry.
   at 0x40192BC: VALGRIND_PRINTF_BACKTRACE (valgrind.h:319)
   by 0x401C823: operator new(unsigned) (vg_replace_malloc.c:164)
   by 0x80487BF: std::vector<char, std::allocator<char> >::reserve(unsigned) new_allocator.h:92)
   by 0x804874D: main (vg.cxx:6)

Я хотел бы изменить свой модульный тест, чтобы просто пропустить проблемный код, когда он запускается из valgrind. Это возможно?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
4 455
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я посмотрел на документацию valgrind и не нашел легкого ответа. Но вот несколько вещей, которые вы можете попробовать:

  • Напишите свою собственную оболочку вокруг новой операции и вызовите исключение до того, как valgrind запустит свою новую частную функцию.

  • Попробуйте, как предложено выше, за исключением того, что вместо параметра командной строки (для которого требуется подключение) используйте переменную среды:

    MYAPP_UNIT_TESTS_DISABLED = "NEW_MINUS_ONE,FLY_TO_MOON,DEREF_NULL" valgrind myapp
    

Тогда вы можете легко написать функцию

bool unit_test_enabled(const char *testname);

для защиты вашего модульного теста на основе значения, возвращаемого getenv (3).

Ответ принят как подходящий

Вы должны посмотреть на эта страница из руководства Valgrind, он содержит макрос RUNNING_ON_VALGRIND (включен в valgrind.h), который делает то, что вы хотите.

Спасибо за это, уже много лет пользуюсь * grind, но интерфейс почти не трогал. Легко сделать разумным включить этот макрос в autoconf .., который автоматически включает мою отладочную printfs () и утверждения при работе под valrgind, если присутствует valgrind / valgrind.h :) Еще раз спасибо! Очень полезно

Tim Post 09.01.2009 10:40

Если кто-то не хочет включать valgrind.h (для чего требуется тест autoconf или аналогичный) или использовать оболочку, вот эвристика для Linux (и других систем, использующих ELF?): Проверьте значение переменной среды LD_PRELOAD, поскольку Valgrind работает путем предварительной загрузки библиотек . Я использую следующий тест на C, чтобы проверить, содержит ли LD_PRELOAD строку "/valgrind/" или "/vgpreload":

int tests_run_within_valgrind (void)
{
  char *p = getenv ("LD_PRELOAD");
  if (p == NULL)
    return 0;
  return (strstr (p, "/valgrind/") != NULL ||
          strstr (p, "/vgpreload") != NULL);
}

В других системах может быть аналогичное решение. Я предлагаю следующую команду, чтобы узнать, упоминает ли среда Valgrind:

valgrind env | grep -i valgrind

Другие вопросы по теме