Как отладить правильно и найти причины для катастрофических отказов?

Я не знаю, что сделать больше... его безнадежное. Я устаю от предположения, что вызывает катастрофические отказы. Недавно я заметил некоторые программы катастрофических отказов вызовов opengl случайным образом на некоторых gfx картах. таким образом, я становлюсь действительно параноиком, что может вызвать катастрофические отказы теперь. Плохая вещь на этом катастрофическом отказе состоит в том, что он отказывает только после долгого времени использования программы, таким образом, я могу только предположить то, что является проблемой.

Я не могу помнить то, что изменяется, я сделал к программе, которая может вызвать катастрофические отказы, ее такое долгое время. Но к счастью предыдущая версия не отказывает, таким образом, я мог просто copypaste некоторый код и тратить впустую 10 часов для наблюдения, в которой точке это начинает отказывать..., я не думаю, что хочу сделать это все же.

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

У меня есть createn свободный "сейф" () функция, он проверяет указатель если не ПУСТОЙ, и затем освобождает память и затем устанавливает указатель в NULL. Разве это не то, как это должно быть сделано?

Я следил за использованием памяти диспетчера задач, и непосредственно перед тем, как оно разрушило его, начал есть в 2 раза больше памяти чем обычно. Также загрузка программы стала экспоненциально медленнее каждый раз, когда я загрузил файлы; первые несколько загрузок не казались намного медленнее друг от друга, но затем это начало быстро удваивать скорости под нагрузкой. Что это должно сказать мне о катастрофическом отказе?

Кроме того, я должен вручную освободить векторы C++ при помощи ясного ()? Или они освобождены после использования автоматически, например, если я выделяю вектор в функции, он будет освобожден каждый раз, когда функция закончилась? Я не храню указатели в векторе.

--

Вскоре: я хочу учиться ловить проклятые ошибки максимально быстро, как я делаю это? Использование Visual Studio 2008.

6
задан Newbie 2 June 2010 в 21:27
поделиться

7 ответов

"Случайный" сбой, который происходит через некоторое время после сложной операции, почти наверняка является результатом повреждения кучи. Ошибки, связанные с повреждением кучи, - это сука , поскольку они обычно проявляются очень далеко от места, которое на самом деле вызвало ошибку. Я предлагаю, поскольку вы работаете в Windows, использовать Application Verifier , который можно бесплатно загрузить с MS.

Запустите AV, настройте его для просмотра вашей программы и включите все параметры, связанные с памятью. Затем запустите вашу программу в отладчике. (Эти две вещи заставят вашу программу работать чрезвычайно медленно.) Дополнительные проверки, которые выполняет AV, надеюсь, приведут к сбою вашей программы в другом месте, чем вы видели до сих пор, но это будет местоположение, которое является настоящей причиной ошибки.

3
ответ дан 17 December 2019 в 00:03
поделиться

Первый вопрос, почему вы используете free () в C ++? Обычно вы должны использовать new / delete для управления памятью или, лучше, new в сочетании с интеллектуальными указателями.

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

Случайные сбои обычно / часто являются ошибками памяти, я бы порекомендовал вам снабдить себя хорошим отладчиком памяти. В Windows это обычно означает Rational Purify или Boundschecker. Конечно, это помогает выяснить, что в первую очередь вызвало сбой, а не обработка состояния нехватки памяти? Размыкание нулевого указателя? Космические лучи?

Учитывая ответ на комментарии в вашем вопросе, вот что я бы сделал:

  • Измените перехват исключений VS2008 так, чтобы он прерывался при нарушении прав доступа.
  • Запустите вашу программу в отладчике, в режиме отладки - не пытайтесь отлаживать исполняемый файл выпуска
  • Попробуйте воспроизвести поведение, которое вы наблюдаете. Это займет больше времени, чем в режиме выпуска, но в конечном итоге вы добьетесь этого. Вы, вероятно, также получите несколько ложных срабатываний.
  • Если вы хорошо представляете, какой (нулевой) указатель будет разыменован, assert () указатель и снова запустите программу в отладчике.
1
ответ дан 17 December 2019 в 00:03
поделиться

Обратите внимание на точку зрения Ноя Робертса и JS Bangs - если вы не знакомы с отладчиком, похоже, вам пора познакомиться.

Я бы также предложил инструмент, похожий на valgrind - см. Этот вопрос SO .

Кроме того, нужно ли вручную освобождать векторы c ++ с помощью clear ()?

Нет.

0
ответ дан 17 December 2019 в 00:03
поделиться

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

Я создал "безопасную" функцию free(), она проверяет указатель, если он не NULL, и освобождает память, а затем устанавливает указатель в NULL.

Проверка на NULL не нужна, потому что стандартная free (которой является VS2008) сделает эту проверку за вас. Но все же возможно освобождение нежелательного указателя, что может вызвать проблемы.

Что касается установки указателя на NULL, то это может помочь, но не является панацеей. Во-первых, возможно, вы не устанавливаете правильный указатель в NULL. Например, если вы сделаете следующее:

void myfree(void *ptr)
{
    free(ptr);
    ptr = NULL;
}

все, что вы сделали, это установили локальный параметр myfree в NULL. Копия указателя вызывающей программы осталась нетронутой.

1
ответ дан 17 December 2019 в 00:03
поделиться

"Я не могу вспомнить, какие изменения я сделал в программе, которые могут вызвать сбои, прошло так много времени. Но к счастью, предыдущая версия не сбоев, так что я мог бы просто вставить некоторый код и потратить 10 часов, чтобы увидеть в какой момент она начнет сбоить..."

Вот почему Test-Driven Development (TDD) - это круто. Прочитайте о ней и узнайте, как она может помочь вам избежать подобных сценариев.

1
ответ дан 17 December 2019 в 00:03
поделиться

Как было сказано ранее, скорее всего, это где-то утечка памяти.

Visual Studio имеет встроенные инструменты для этого

Обычно вы делаете два снимка памяти и сравниваете их в какой-то момент

1
ответ дан 17 December 2019 в 00:03
поделиться

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

0
ответ дан 17 December 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: