Интерпретация исключений нарушения доступа?

У нас есть специальное приложение, которое мы используем, построенное на коде VB / C ++.
Этот код будет работать в течение нескольких дней, недель, месяцев, и это не приведет к ошибке исключения.

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

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

Любая информация или рекомендации по прочтению исключения или его использованию, а затем по устранению неполадок будут полезны. Тест ниже копируется из журнала Windows, когда событие было сгенерировано.

Заранее благодарю за любую помощь.

Application: Epic.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.AccessViolationException [![enter image description here][1]][1]
at MemMap.ComBuf.IsCharAvailable(Int32)
at HMI.frmPmacStat.RefreshTimer_Elapsed(System.Object, System.Timers.ElapsedEventArgs)
at System.Timers.Timer.MyTimerCallback(System.Object)
at System.Threading.TimerQueueTimer.CallCallbackInContext(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.TimerQueueTimer.CallCallback()
at System.Threading.TimerQueueTimer.Fire()
at System.Threading.TimerQueue.FireQueuedTimerCompletion(System.Object)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

введите описание изображения здесьвведите описание изображения здесь

0

Решение

Существуют исключения, которые вызываются средой выполнения c ++ в результате выполнения выражения throw, и существуют другие типы ошибок, вызванных операционной системой или аппаратным обеспечением, перехватывающим вашу инструкцию. Неверный доступ к памяти, как правило, не генерируется кодом в c ++, но является побочным эффектом при оценке выражения, пытающегося получить доступ к памяти по недействительному адресу, в результате чего ОС сигнализирует о процессе, обычно убивая его. Поскольку он находится за пределами C ++, он, как правило, зависит от платформы, но типичные ошибки:

  • чтение нулевого указателя
  • используя указатель на объект, который был удален
  • выход за пределы допустимого диапазона элементов массива
  • использование недействительных итераторов в контейнерах STL

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

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

2

Другие решения

Как уже отмечали другие, этот тип ошибки сложно определить, не копаясь в коде и не выполняя тесты (автоматические или ручные). Чем больше фрагментов системы вы сможете извлечь и воспроизвести, тем лучше. Разделяй и властвуй — твой друг здесь.

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

  1. Приложение отслеживает возможные ошибки во время работы приложения. Это приводит к значительному замедлению вашей программы (замедление в 10 и более раз). Примеры включают в себя:
    1. от Microsoft Проверка приложения
    2. Открытый код и кроссплатформенность Доктор памяти
    3. Google-х ночлежка. В отличие от двух предыдущих программ, эта требует использования вашего кода. Это также (якобы — не пробовал) легче использовать с такими помощниками, как Коммерческая интеграция Backtrace для анализа вывода Crashpad
    4. Google-х Дезинфицирующие — бесплатно, а некоторые встроены в gcc и clang. Там также есть Порт Windows Address Sanitizer, но беглый взгляд предполагает, что это может быть немного второсортный гражданин.
    5. Если вы можете запустить и воспроизвести его также на Linux, вы можете использовать Valgrind; р-р (увидеть это CppCast EP), которое является бесплатным расширением для GDB, которое записывает и воспроизводит вашу программу, чтобы вы могли записать сеанс отладки, который потерпел неудачу, и затем пройти через него, чтобы увидеть, что пошло не так; и / или UndoDB и друзья из программного обеспечения Undo, более сложного, коммерческого продукта, такого как rr.
  2. Статический анализ кода. Это набор инструментов, который ищет типичные ошибки в вашем коде. Как правило, он имеет низкое отношение сигнал / шум, поэтому есть много мелких вещей, которые нужно изучить, если вы запустите его на большом существующем проекте (лучше всего начать проект, используя эти вещи с самого начала, если это возможно). Тем не менее, многие из предупреждений неоценимы. Примеры:
    1. Большинство компиляторов имеют встроенную часть этой функциональности. Если вы используете Visual Studio, добавьте /W4 /WX на ваши флаги компиляции для кода C ++, чтобы заставить максимальные предупреждения, а затем исправьте все предупреждения. Для gcc и clang добавьте ‘-Wall -Wpedantic -Werror`, чтобы не вызывать предупреждений.
    2. PVS-Studio (Коммерческий)
    3. PC-Lint (Коммерческий)
  3. Если вы можете использовать код для записи сообщений журнала, что-то вроде DebugView ++ может быть полезным.

Ситуация усложняется, если у вас происходит многопоточность, что выглядит так, как вы делаете, потому что недетерминированность становится все труднее отслеживать, появляются новые классы возможных ошибок, и некоторые из вышеперечисленных инструментов не будут работать хорошо ( например, я думаю, что rr является только однопоточным). Помимо полноценной IDE, такой как Visual Studio, вам понадобится что-то вроде Intel Инспектор (ранее Intel Thread Checker), или в Linux, Valgrind’s Helgrind а также DRD и ThreadSanitizer (в приведенных выше дезинфицирующих средствах, но также и в Linux только AFAIK). Но, надеюсь, этот список дает вам место для начала.

1

По вопросам рекламы [email protected]