Попытка прочитать или записать в защищенную память. Это часто указывает на то, что другая память повреждена.

151

Я надеюсь, что кто-нибудь сможет объяснить мне, что могло вызвать эту ошибку:

Попытка прочитать или записать в защищенную память. Это часто указывает на то, что другая память повреждена.

Я не могу опубликовать код, потому что эта ошибка, кажется, возникает в любой случайной области приложения. Приложение будет работать от 12 до 48 часов, прежде чем выдаст ошибку. Иногда он останавливается в, казалось бы, случайном месте и выдает указанную выше ошибку, в других случаях все приложение останавливается, и я получаю экран с ошибкой, в которой говорится что-то вроде «Произошла фатальная ошибка в ... Это может быть ошибка в CLR или ... "что-то о PInvoke или другой нерелевантной информации. Когда это происходит, все потоки отображаются как завершенные и нет доступной отладочной информации.

Вкратце, это то, что делает приложение:

Это многопоточное серверное приложение, полностью написанное на C #. Клиенты подключаются к серверу через сокет. Сервер запускает виртуальную «среду» для клиентов, где они могут взаимодействовать друг с другом и со средой. Он потребляет довольно много памяти, но я не вижу утечки. Обычно он занимает около 1,5 ГБ. Я не думаю, что это утечка, потому что использование памяти остается относительно постоянным на протяжении всего времени работы приложения. Его постоянно работающий код для поддержки среды, даже если клиенты ничего не делают. Он не использует стороннее программное обеспечение или другие API. Единственные внешние ресурсы, которые использует это приложение, - это соединения сокетов и соединения с базой данных SQL. Он работает на 64-битном сервере. Я пробовал отлаживать это в VS2008 и VS2010, используя .net 2.0, 3.5 и 4.

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

Кто-нибудь другой
источник
пожалуйста, опубликуйте полный стек вызовов ...
Митч Уит
Примерно в половине случаев я не могу получить стек вызовов. Если это вызывает фатальную ошибку выполнения, отладочной информации нет вообще. Когда он действительно останавливается где-то в коде, ничего не кажется ненормальным. Я даже просмотрел все активные потоки и не увидел ничего, что могло бы вызвать конфликт. Я предполагаю, что повреждение памяти произошло за некоторое время до того, как возникла ошибка.
Someone Else
Проверьте, не используются ли старые дрянные компоненты COM и ActiveX. Я также знаю, что SQLCE выкидывает подобные вещи в многопоточной среде.
leppie
Компонентов COM или ActiveX нет.
Someone Else

Ответы:

53

Я только что столкнулся с этой проблемой в VS 2013 .NET 4.5 с DLL MapInfo. Оказывается, проблема заключалась в том, что я изменил платформу для сборки с x86 на Any CPU, и этого было достаточно, чтобы вызвать эту ошибку. Смена его обратно на x86 помогала. Может кому-нибудь помочь.

Сергей
источник
1
как ты поменял обратно на х86. У меня такая же проблема с этой инструкцией CSingleLock lock(&m_csMember, TRUE);. Для более подробной информации, вот мой пост
ABCmo
В VS 2012/2013 перейдите в Project Properties-> Build и измените «Platform Target» на все, что вам нужно. Хотя я думаю, что есть другое место, где вы можете это изменить, но я не могу его найти, я думаю, что любой способ должен достичь того же результата.
Сергей
На самом деле я использую VS 2013, и он настроен как x86: /
ABCmo
1
Ваша проблема может быть вызвана многими вещами, я был очень удивлен, что исправил свою проблему, изменив платформу сборки. Можно сказать, удачный побег.
Сергей
Это решение в сочетании с этим ответом решило это для меня.
Zach Posten
24

Я также столкнулся с этой проблемой с Visual Studio (VS) 2010. Что еще интереснее, у меня было несколько проектов в моем решении (консольное приложение, приложение WPF, приложение Windows Forms), но оно давало сбой только тогда, когда я устанавливал тип «Консольное приложение» проекта в качестве стартового проекта решения (даже для тех, у которых буквально не было кода или каких-либо дополнительных сборок, упомянутых помимо тех, которые по умолчанию поставляются с самим шаблоном проекта).

Следующее изменение, наконец, помогло мне решить проблему: перейдите к свойствам проекта проекта консольного приложения (в качестве альтернативы выберите файл проекта в проводнике решений и нажмите комбинацию клавиш Alt+ Enter) -> Перейти на Debugвкладку -> Прокрутите до Enable Debuggersраздела на правой панели -> Проверить установите Enable unmanaged code debuggingфлажок, как показано на снимке ниже -> Нажмите Floppyкнопку на панели инструментов, чтобы сохранить свойства проекта. Первопричина того, почему это произошло, мне до сих пор не известна. Единственное, что я заметил, это то, что прошлой ночью на моем компьютере было установлено множество обновлений Windows, которые в основном состояли из обновлений офиса и обновлений ОС (более десятка статей в КБ).

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

Обновление : VS 2017 и далее имя настройки изменилось, как показано на снимке экрана ниже:

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

RBT
источник
1
В VS 2017 это было переименовано в « Включить отладку собственного кода »
Chiramisu
1
Спасибо @Chiramisu за предоставление последней информации и помощь сообществу. Я обновил ответ, чтобы он подходил для более новых версий Visual Studio.
RBT
20

Наконец отследил это с помощью WinDBG и SOS. Нарушение прав доступа было вызвано какой-то неизвестной DLL. Оказалось, что проблема была в программном обеспечении под названием «Nvidia Network Manager». Я бесчисленное количество раз читал, как эта проблема может быть вызвана брандмауэрами или антивирусом, ни один из которых я не использую, поэтому я отклонил эту идею. Кроме того, я исходил из предположения, что это не связано с окружающей средой, потому что это происходит на более чем 1 сервере с использованием разного оборудования. Оказалось, что на всех машинах, на которых я это тестировал, был запущен "NVidia Network Manager". Я считаю, что он устанавливается вместе с остальными драйверами материнской платы.

Надеюсь, это кому-то поможет, поскольку эта проблема очень долго беспокоила мое приложение.

Кто-нибудь другой
источник
1
в моем случае, когда я часто читаю данные с устройства, его ошибка выброса, я остановил поток на некоторое время, используя Thread.Sleep (1000) для следующего чтения. и работает отлично.
JRB
6
Я бы предположил, что лекарство было «удалить NVidia Network Manager»
Пол
81
Ответ, получивший наибольшее количество голосов, не дает логического ответа.
Теоман Шипахи
Я сомневаюсь, что у меня есть что-то связанное с nvidia на моей материнской плате или в моем программном обеспечении. Я использую Visual Studio 2010. Проблема возникает только при отладке проекта из VS. Его выходной exe из папки отладки работает отлично.
RBT,
1
Я обращаюсь к потокам моего собственного процесса, которые вызывают проблему.
Мухаммад Сакиб
13

Проблема может быть связана с DLL смешанных платформ сборки в проекте. т.е. вы создаете свой проект для любого процессора, но у вас есть некоторые библиотеки DLL в проекте, уже созданные для платформы x86. Это вызовет случайные сбои из-за различного отображения памяти 32-битной и 64-битной архитектуры. Если все библиотеки DLL созданы для одной платформы, проблема может быть решена.

Мухаммад Юсуф Сулахрия
источник
8

Эта ошибка не должна происходить в управляемом коде. Это может решить проблему:

Перейдите в отладчик Visual Studio, чтобы обойти это исключение:

Tools menu ->Options -> Debugging -> General -> Uncheck this option "Suppress JIT optimization on module load"

Надеюсь, это поможет.

любопытный мальчик
источник
3
Мне жаль, что у вас не получилось. Я подумал, что эта ошибка возникает по множеству причин, решение, которое я опубликовал, может решить проблему для кого-то другого, если причина заключается в оптимизации JIT.
curiousBoy
6

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

Проблема, похоже, связана с установкой .NET 4.5.1.

Я загрузил и установил .NET 4.5.2 (мои проекты все еще ссылаются на .NET 4.5.1), и проблема решена.

Источник решения:

https://connect.microsoft.com/VisualStudio/feedback/details/819552/visual-studio-debugger-throws-accessviolationexception

gb2d
источник
5

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

Какая у вас ОС и пакет обновления?

Митч Уит
источник
1
Запуск XP 64 SP2. Однако это произошло на нескольких серверах. Я прошел через все так много раз, и я не вижу ничего, что не является потокобезопасным. Также не будет ли я получать ошибку изменения коллекции, а не нарушение доступа?
Someone Else
5

У меня возникла эта проблема недавно, когда я сменил сервер разработки для проекта. Я получал эту ошибку в строке кода, где объявил новую переменную OracleConnection.

Попробовав множество вещей, включая установку исправлений, я попытался изменить ссылки Oracle.DataAccess и System.Data.OracleClient в проекте, и это сработало!

Когда проект переносится на новую машину, я предлагаю вам обновить все ссылки, добавленные в этот проект.

deepakg_rao
источник
5

Я получил эту ошибку при использовании pinvoke в методе, который принимает ссылку на файл StringBuilder. Я использовал конструктор по умолчанию, который, по-видимому, выделяет только 16 байт. Windows попыталась поместить в буфер более 16 байт и вызвала переполнение буфера.

Вместо того

StringBuilder windowText = new StringBuilder(); // Probable overflow of default capacity (16)

Используйте большую емкость:

StringBuilder windowText = new StringBuilder(3000);
Чарли
источник
4

Вы пробовали отключить DEP (предотвращение выполнения данных) для своего приложения?

Альхазен
источник
2
Не уверен, что это хорошая идея. Это вполне может отсрочить аварию, но за счет нанесения большего ущерба. Я думаю, что лучшая идея, если вы собираетесь вылететь, - это вылететь раньше :-)
paxdiablo
1
Отключение DEP неразумно, но полезно для диагностики.
vcsjones 02
4

Это почти всегда простой вопрос. Код плохой. Это редко инструменты, просто статистический анализ. Бесчисленные миллионы людей используют Visual Studio каждый день, и, возможно, некоторые из них используют ваш код - какой фрагмент кода лучше тестируется? Я гарантирую, что если бы это была проблема с VS, мы, вероятно, уже нашли бы ее.

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

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

  • неинициализированные указатели или другие значения.
  • записывает в буфер больше, чем его размер.
  • ресурсы, совместно используемые потоками, которые не защищены мьютексами.

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

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

Я недостаточно знаком с VS, чтобы знать, но вы также можете изучить возможность использования инструмента отслеживания памяти (например, valgrind для Linux), чтобы увидеть, может ли он обнаружить какие-либо очевидные проблемы.

Paxdiablo
источник
3
Вы также можете получить поврежденный указатель из-за плохой памяти. Если этого не происходит на сервере с памятью ECC, попробуйте утилиту длительного тестирования памяти, чтобы устранить причину, связанную с оборудованием.
cdonner 02
12
Я знаю, что это не проблема с оборудованием, потому что это происходит на нескольких серверах. Спасибо, что указали, что в коде очевидно что-то плохое. Я не виню визуальную студию. Как указано, приложение работает нормально в течение случайного периода времени. Его непросто воспроизвести, и я уже несколько недель пытаюсь определить проблему.
Someone Else
5
@Someone Else: Я не думаю, что обзывание поможет вам.
Митч Уит
2
@Someone Else, я помог, насколько мог, предоставив ограниченную информацию, которую вы предоставили. Даже лучший врач в мире не может много сделать с пациентом, который просто заявляет: «Мне больно» :-) Если вы хотите предоставить более конкретную информацию, возможно, мы сможем больше помочь.
paxdiablo
5
Плохой ответ, но подход, бесстыдные предположения, необоснованные предположения, решение не предоставлено ... Почему этот ответ все еще открыт? И какие 3 человека могли проголосовать за этот ответ?
ThunderGr
4

Я столкнулся с той же проблемой. Мой код представлял собой DLL-библиотеку .NET (расширение AutoCAD), работающую внутри AutoCAD 2012. Я также использую Oracle.DataAccess, и мой код генерировал то же исключение во время ExecuteNonQuery (). Я, к счастью, решил эту проблему, изменив версию .net ODP, которую я использовал (то есть Oracle.DataAccess 2.x).

kmxr
источник
Я столкнулся с той же проблемой - autocad .net dll - не могли бы вы рассказать, в чем была проблема и как ее исправить?
BKSpurgeon
3

Поддающийся проверке код не должен повреждать память, поэтому происходит что-то небезопасное. Используете ли вы где-нибудь небезопасный код, например, при обработке буфера? Кроме того, сведения о PInvoke могут не иметь значения, поскольку PInvoke включает переход к неуправляемому коду и связанный с ним маршалинг.

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

Дэн Брайант
источник
В сообщении об ошибке упоминается PInvoke как возможная причина. Небезопасного кода нет. Попробую WinDBG. Спасибо.
Someone Else
3

Хорошо, это могло быть довольно бесполезно и просто анекдотично, но ...

Это исключение постоянно генерировалось некоторыми библиотеками Twain32, которые мы использовали в моем проекте, но могло произойти только на моей машине.

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

И это сработало.

Оказывается, библиотеки Twain32 пытались указать мой телефон как устройство, совместимое с Twain, и что-то, что он сделал в этом процессе, вызвало это исключение.

Иди разбери ...

Альмуло
источник
2

в моем случае файл был открыт и поэтому заблокирован.

Я получал это при попытке загрузить файл Excel с помощью LinqToExcel, который также был открыт в Excel.

это все, что я сделал

    var maps = from f in book.Worksheet<NavMapping>()
                select f;
    try {
        foreach (var m in maps)
            if (!string.IsNullOrEmpty(m.SSS_ID) && _mappings.ContainsKey(m.SSS_ID))
                _mappings.Add(m.SSS_ID, m.CDS_ID);
    } catch (AccessViolationException ex) {
        _logger.Error("mapping file error. most likely this file is locked or open. " + ex);
    }
Sonic Soul
источник
2

У меня такая же ошибка в проекте, над которым я работал в VB.NET. Проверка «Включить платформу приложения» на странице свойств решила эту проблему.

Тони Рэймонд
источник
1

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

ако
источник
1

Получил эту ошибку случайным образом в VS1017 при попытке создать проект, который накануне строился отлично. После перезагрузки ПК проблема сработала (я также заранее выполнил следующую команду, не уверен, требуется ли она: сброс netsh winsock)

Вечный21
источник
1
Это как раз моя ситуация с VS 2017 - System.AccessViolationException: попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена. Я просто перезагрузил компьютер, чтобы решить эту проблему, больше ничего не делая.
Гонконг
0

Мой ответ во многом зависит от вашего сценария, но у нас возникла проблема с попыткой обновить приложение .NET для клиента, которому более 10 лет, чтобы они могли заставить его работать в Windows 8.1. Ответ @alhazen был для меня примерно правильным. Приложение полагалось на стороннюю DLL, за обновление которой клиент не хотел платить (Pegasus / Accusoft ImagXpress). Мы переназначили приложение для .NET 4.5, но каждый раз при выполнении следующей строки мы получали AccessViolationException was unhandledсообщение:

UnlockPICImagXpress.PS_Unlock (1908228217,373714400,1341834561,28447);

Чтобы исправить это, нам пришлось добавить в проект следующее событие post-build:

call "$(DevEnvDir)..\tools\vsvars32.bat"
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\editbin.exe" /NXCOMPAT:NO "$(TargetPath)"

Это явно указывает на то, что исполняемый файл несовместим с предотвращением выполнения данных. Подробнее см. Здесь .

Барри
источник
0

В некоторых случаях это может произойти, когда:

obj = new obj();
...
obj.Dispose();  // <-----------------    Incorrect disposal causes it
obj.abc...
Т. Тодуа
источник
0

В моем случае мне пришлось ссылаться на библиотеку C / C ++ с помощью P / Invoke, но я должен был сначала убедиться, что память была выделена для выходного массива, используя fixed:

[DllImport("my_c_func_lib.dll", CharSet = CharSet.Ansi)]
public static extern unsafe int my_c_func(double input1, double input2, double pinput3, double *outData);

    public unsafe double[] GetMyUnmanagedCodeValue(double input1, double input2, double input3)
    {
        double[] outData = new double[24];

        fixed (double* returnValue = outData)
        {
            my_c_func(input1, input2, pinput3, returnValue);
        }

        return outData;
    }

Подробнее см. Https://www.c-sharpcorner.com/article/pointers-in-C-Sharp/

user8128167
источник
0

Это случилось со мной, когда я отлаживал свое приложение C # WinForms в Visual Studio. Мое приложение обращается к материалам Win32 через DllImport, например

[DllImport("Secur32.dll", SetLastError = false)]
private static extern uint LsaEnumerateLogonSessions(out UInt64 LogonSessionCount, out IntPtr LogonSessionList);

Запуск Visual Studio «от имени администратора» решил проблему для меня.

Netricity
источник
0

У меня было такое же сообщение об ошибке:

System.AccessViolationException: попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена.

В моем случае ошибка исчезла после очистки и повторной сборки решения.

Вивек Шарма
источник
0

В моем случае утилита FTDI FT Prog выдавала ошибку при сканировании USB-устройств. Проблема была решена путем отключения наушников Bluetooth от компьютера.

101
источник
0

Я получил это сообщение об ошибке в лямбда-выражении, которое использовало Linq для фильтрации коллекции объектов. Когда я осмотрел коллекцию, то заметил, что ее элементы не были заполнены - в Localsокне при их раскрытии просто отображалось «...». В конечном итоге проблема заключалась в методе репозитория, который изначально заполнял коллекцию - Dapper пытался автоматически сопоставить свойство вложенного объекта. Я исправил запрос Dapper для обработки мульти-сопоставления и исправил ошибку памяти.

мелисент
источник