Идеи для отладки и решения очень спорадического сбоя - кажется, AV - PullRequest
2 голосов
/ 19 сентября 2009

У меня где-то есть ошибка, из-за которой мое приложение просто исчезает без сообщения об ошибке или чего-то в этом роде. Приложение просто исчезает с экрана и больше не отображается в диспетчере задач.

Приложение является приложением C ++ Builder (CBuilder2007), и я попробовал все, что у меня возникло, чтобы попытаться поймать эту ошибку. Это происходит очень-очень редко, никогда не падало на моей машине и только один раз на тестовых машинах, которые есть у нас в офисе. С одним из наших клиентов это происходит немного чаще, но мы не нашли способ сделать это или найти обстоятельства, где это происходит. Это тяжелое многопоточное приложение.

Я включил madExcept в этом приложении, но он ничего не ловит. Я уже добавил обработчики, использующие подпрограммы set_terminate и set_unexpected RTL, но безуспешно.

Единственная информация, которую я имею, получена из обертки «приложения-загрузчика», чтобы получить код возврата из основного приложения. Он завершается с кодом C0000005, что, по-моему, означает нарушение прав доступа. Странно то, что, как уже упоминалось, нет даже окна ошибки Windows или чего-то подобного.

Вопрос будет: есть идеи, чтобы попытаться поймать это? Поскольку я даже понятия не имею, где это может происходить (у меня много журналов вокруг приложения, но «след» до падения приложения ни к чему не привел), моя идея с set_terminate и set_unexpected Подпрограммы должны были получить трассировку стека, чтобы попытаться увидеть, где была сгенерирована ошибка, но пока эти подпрограммы вообще не вызываются (по крайней мере, единственный раз, когда это происходило здесь, в моем офисе)

Заранее спасибо


[Обновление 22.Sept.2009] Используя AddVectoredHandlerException, я смог получить колл-стэк от сбоя, и теперь я могу начать пытаться изолировать и исправить ошибку. Спасибо !!!

Ответы [ 11 ]

6 голосов
/ 19 сентября 2009

terminate / unexpected вызывается только во время выполнения C ++ и только для исключений C ++.

Нарушение прав доступа - исключение SEH - чтобы его отловить, вам нужно SetUnhandledExceptionFilter или AddVectoredExceptionHandler (если это> = XP). Затем вы могли бы создать мини-дамп, используя MiniDumpWriteDump и связанный с ним.

3 голосов
/ 20 сентября 2009

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

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

Однако, если программа действительно мгновенно завершает работу, как я видел это, то даже обработчик, зарегистрированный с SetUnhandledExceptionFilter, не поможет. Программа останавливает все выполнение и выпадает из памяти до того, как обработчик когда-либо будет вызван.

Хотя на ум приходит несколько идей:

  • Проверьте кодовую базу на предмет использования TerminateProcess или TerminateThread . Я могу ошибаться, но я верю, что их использование может вызвать симптомы, которые вы видите.
  • Проверьте любое использование указателей на функции, включая обратные вызовы и WindowProc, передаваемые API-интерфейсам Window. Убедитесь, что соглашения о вызовах, списки параметров и возвращаемые значения совпадают. Если указатель функции приведен для компиляции кода, он может скрывать несоответствие, которое может привести к возникновению плохих вещей.
  • Рассмотрите любые сторонние библиотеки или компоненты (ActiveX или подобные), которые вы используете. Возможно, у них есть ошибка в их собственном коде, вызывающая эту проблему в непонятных ситуациях. Вы могли бы попытаться разместить операторы регистрации до и после вызовов их функций, чтобы увидеть, может ли это определить, где останавливается программа.
  • И если больше ничего не помогает, добавьте больше записей в свой собственный код.

А по поводу ведения журнала: когда мне нужно было помочь отследить проблему, подобную этой, где на моей работе мы закончили тем, что создали механизм ведения журнала, который создавал бы журнал с уникальным именем при каждом запуске программы и удалял его, если программа закончилась нормально. Таким образом, каждый раз при возникновении проблемы завершения будет существовать другой файл журнала. Мы использовали отметку даты и времени как часть уникального аспекта именования. Содержимое журналов было просто записью, какие действия происходили в программе. Мы прошли несколько итераций по изучению журналов, а затем добавляли больше операторов, пока это не привело нас к источнику. И, отслеживая проблему, этот механизм дал нам очень четкое представление о частоте возникновения проблемы. Вы могли бы рассмотреть что-то подобное.

1 голос
/ 21 сентября 2009

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

Если бы это была моя проблема, я бы попробовал осуществлять мониторинг с помощью Process Monitor от sysinternals. Настройте его на просмотр только вашего процесса и убедитесь, что он поддерживается файлом, если это займет много времени. Это может сказать вам, какой поток активен и что происходит, когда процесс заканчивается. Вы также можете попытаться найти эквивалент «фермы» для Windows - программы для мониторинга системных вызовов.

1 голос
/ 20 сентября 2009

Может быть, добавление хорошего старомодного обработчика сигнала может хотя бы дать некоторое представление о том, что произошло?

1 голос
/ 20 сентября 2009

Re: приложение исчезает, на компьютерах клиентов отключена настройка «Сообщить об ошибках» в Windows? Он скрыт в панели управления «Система», и при выключении обычное диалоговое окно уведомления о сбое Windows закрывается.

1 голос
/ 20 сентября 2009

Вы должны запустить свое приложение в режиме отладки и выполнить стресс-тест, запуская множество сложных сценариев все больше и больше, чтобы вы могли отловить исключение в режиме отладки.

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

1 голос
/ 19 сентября 2009

Я уже дважды видел, как это происходит с кодом C ++:

  1. При динамической загрузке Windows API с использованием LoadLibrary и GetProcAddress и последующем вызове его через указатель функции, объявленный с неправильным соглашением о вызовах (он должен был иметь __stdcall, но не). *

  2. Где класс имел указатель функции в качестве переменной-члена, и указатель функции вызывался до инициализации.

0 голосов
/ 21 сентября 2009

Запустите ваше приложение, затем подключите windbg (режим сбоев), чтобы при первом появлении исключения второго шанса генерировался дамп. Не забудьте поместить файлы символов (PDB).

0 голосов
/ 21 сентября 2009

Подписаться на отчеты об ошибках Windows. Скорее всего, некоторые из ваших клиентов сообщат об AV в Microsoft, которая с радостью поделится с вами собранными следами стека. В качестве преимущества вы получаете точные данные о надежности вашего приложения. Управление любит тех. Например. Вы можете установить цель «снизить частоту ошибок на 50% к 2010 году».

0 голосов
/ 20 сентября 2009

Сконфигурируйте ваше приложение для записи минидампа в случае сбоя.

Я не уверен, как это происходит в CBuilder, но в Visual Studio вы можете напрямую загрузить этот дамп, и он покажет вам полный стек вызовов и строку исходного кода, которая вызвала сбой.

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

...