Podjęto próbę odczytania lub zapisu chronionej pamięci. Często wskazuje to na uszkodzenie innej pamięci


144

Mam nadzieję, że ktoś może mnie oświecić, co może być przyczyną tego błędu:

Podjęto próbę odczytania lub zapisu chronionej pamięci. Często wskazuje to na uszkodzenie innej pamięci.

Naprawdę nie mogę wysłać kodu, ponieważ ten błąd wydaje się być wyrzucany w dowolnym przypadkowym obszarze aplikacji. Aplikacja będzie działać w dowolnym miejscu od 12 do 48 godzin przed zgłoszeniem błędu. Czasami zatrzyma się w pozornie przypadkowym miejscu i wyrzuci powyższy błąd, innym razem cała aplikacja zatrzymuje się i pojawia się ekran z błędem, który mówi coś w rodzaju „Wystąpił błąd krytyczny w ... To może być błąd w CLR lub ... "coś o PInvoke lub inne nieistotne informacje. W takim przypadku wszystkie wątki są zakończone i nie ma dostępnych informacji o debugowaniu.

W skrócie to, co robi aplikacja:

Jest to wielowątkowa aplikacja serwerowa napisana w całości w języku C #. Klienci łączą się z serwerem przez gniazdo. Na serwerze działa wirtualne „środowisko” dla klientów, w którym mogą oni współdziałać ze sobą i ze środowiskiem. Zużywa sporo pamięci, ale nie widzę przecieków. Zwykle zużywa około 1,5 GB. Nie sądzę, żeby przeciekał, ponieważ użycie pamięci pozostaje względnie stałe przez cały czas działania aplikacji. Jego stale działający kod, aby utrzymać środowisko, nawet jeśli klienci nic nie robią. Nie używa oprogramowania innych firm ani innych interfejsów API. Jedynymi zewnętrznymi zasobami, z których korzysta ta aplikacja, są połączenia gniazd i połączenia z bazą danych SQL. Działa na serwerze 64-bitowym. Próbowałem debugować to w VS2008 i VS2010 przy użyciu .net 2.0, 3.5 i 4.

Próbowałem wyłączyć optymalizacje kompilatora i kilka poprawek Microsoft. Wydaje się, że nic nie usuwa tego problemu. Byłoby docenione, gdyby ktoś znał jakiekolwiek możliwe przyczyny lub jakiś sposób na zidentyfikowanie przyczyny problemu.


proszę o przesłanie pełnego stosu zgłoszeń ...
Mitch Wheat


Mniej więcej w połowie przypadków nie mogę uzyskać stosu wywołań. Jeśli zgłasza krytyczny błąd wykonania, nie ma żadnych informacji o debugowaniu. Czas, w którym faktycznie zatrzymuje się gdzieś w kodzie, nic nie wydaje się nienormalne. Przeszedłem nawet przez wszystkie aktywne wątki i nie widziałem niczego, co mogłoby spowodować konflikt. Zakładam, że uszkodzenie pamięci nastąpiło jakiś czas, zanim wyrzuciło błąd.
Ktoś inny

Sprawdź, czy używane są kiepskie, stare komponenty COM i ActiveX. Wiem też, że takie kości SQLCE są używane w środowisku wielowątkowym.
leppie

Nie ma składników COM ani ActiveX.
Ktoś inny

Odpowiedzi:


50

Właśnie napotkałem ten problem w VS 2013 .NET 4.5 z biblioteką DLL MapInfo. Okazuje się, że problem polegał na tym, że zmieniłem platformę do kompilacji z x86 na dowolny procesor i to wystarczyło, aby wywołać ten błąd. Zmiana z powrotem na x86 załatwiła sprawę. Może komuś pomóc.


1
jak zmieniłeś to z powrotem w x86. Po prostu napotykam ten sam problem z tą instrukcją CSingleLock lock(&m_csMember, TRUE);. Po więcej szczegółów, oto mój post
ABCmo

W VS 2012/2013 przejdź do Project Properties-> Build i zmień „Platform Target” na cokolwiek potrzebujesz. Chociaż myślę, że jest inne miejsce, w którym możesz to zmienić, ale wydaje mi się, że nie mogę go znaleźć, myślę, że każdy sposób powinien przynieść ten sam rezultat.
Siergiej

Właściwie używam VS 2013 i jest skonfigurowany jako x86: /
ABCmo

1
Twój problem może być spowodowany wieloma rzeczami, byłem naprawdę zaskoczony, że naprawiłem swój problem, zmieniając platformę kompilacji. Można powiedzieć, że to szczęśliwa ucieczka.
Sergey

To rozwiązanie w połączeniu z tą odpowiedzią rozwiązało to za mnie.
Zach Posten

23

Z tym problemem spotkałem się również w Visual Studio (VS) 2010. Co ciekawe, miałem kilka projektów w swoim rozwiązaniu (aplikacja konsoli, aplikacja WPF, aplikacja Windows Forms), ale kończyło się to tylko wtedy, gdy ustawiałem typ „Aplikacja konsolowa” projektu jako projekt początkowy rozwiązania (nawet dla tych, które dosłownie nie miały kodu ani żadnych dodatkowych zestawów, o których mowa poza domyślnymi, które są dostarczane z samym szablonem projektu).

Następująca zmiana w końcu pomogła mi rozwiązać problem: Przejdź do właściwości projektu aplikacji konsolowej (Alternatywnie wybierz plik projektu w eksploratorze rozwiązań i naciśnij kombinację klawiszy Alt+ Enter) -> Przejdź do Debugzakładki -> Przewiń doEnable Debuggers sekcji w prawym panelu -> Sprawdź Enable unmanaged code debuggingpole wyboru, jak pokazano w poniższej migawce -> Kliknij Floppyprzycisk na pasku narzędzi, aby zapisać właściwości projektu. Główna przyczyna, dla której tak się stało, nadal nie jest mi znana. Jedyną rzeczą, jaką zauważyłem, było to, że było wiele aktualizacji systemu Windows, które zostały zainstalowane na moim komputerze poprzedniej nocy, które obejmowały głównie aktualizacje pakietu Office i aktualizacje systemu operacyjnego (ponad tuzin artykułów KB).

wprowadź opis obrazu tutaj

Aktualizacja : od VS 2017 nazwa ustawienia uległa zmianie, jak pokazano na poniższym zrzucie ekranu:

wprowadź opis obrazu tutaj


1
Od VS 2017 nazwa została zmieniona na „ Włącz natywne debugowanie kodu
Chiramisu

1
Dzięki @Chiramisu za dostarczanie aktualnych informacji i pomoc społeczności. Zaktualizowałem odpowiedź, aby była odpowiednia dla nowszych wersji programu Visual Studio.
RBT

19

Wreszcie wyśledziliśmy to za pomocą WinDBG i SOS. Naruszenie dostępu było zgłaszane przez nieznaną bibliotekę DLL. Okazuje się, że problem powodował oprogramowanie o nazwie „Nvidia Network Manager”. Czytałem niezliczoną ilość razy, jak ten problem może być spowodowany przez zapory ogniowe lub program antywirusowy, z których żadnego nie korzystam, więc odrzuciłem ten pomysł. Zakładałem również, że nie jest to środowiskowe, ponieważ występuje na więcej niż 1 serwerze korzystającym z innego sprzętu. Okazało się, że wszystkie maszyny, na których to testowałem, działały z programem „NVidia Network Manager”. Wydaje mi się, że instaluje się z resztą sterowników płyty głównej.

Mam nadzieję, że to komuś pomoże, ponieważ ten problem nękał moją aplikację przez bardzo długi czas.


1
w moim przypadku, gdy często czytam dane z urządzenia, jego błąd rzucania, przez pewien czas zatrzymywał wątek, używając Thread.Sleep (1000) do następnego odczytu. i działa idealnie.
JRB

6
Przypuszczałem, że lekarstwem jest „odinstaluj NVidia Network Manager”
paulm,

79
Większość głosowała odpowiedź, która nie daje logicznej odpowiedzi.
Teoman shipahi

Wątpię, czy na mojej płycie głównej lub w moim oprogramowaniu jest coś związanego z nvidią. Używam Visual Studio 2010. Problem występuje tylko podczas debugowania projektu z VS. Plik wyjściowy z folderu debugowania działa doskonale.
RBT

1
Uzyskuję dostęp do wątków mojego własnego procesu, które powodują problem.
Muhammad Saqib

13

Problem może wynikać z bibliotek DLL platform kompilacji mieszanych w projekcie. tj. budujesz swój projekt na dowolnym procesorze, ale masz już kilka bibliotek DLL w projekcie zbudowanym dla platformy x86. Spowoduje to przypadkowe awarie z powodu różnych mapowań pamięci w architekturze 32-bitowej i 64-bitowej. Jeśli wszystkie biblioteki DLL są zbudowane dla jednej platformy, problem można rozwiązać.



8

Ten błąd nie powinien wystąpić w kodzie zarządzanym. To może rozwiązać problem:

Przejdź do debugera programu Visual Studio, aby ominąć ten wyjątek:

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

Mam nadzieję, że to pomoże.


3
Przepraszam, że to nie zadziałało. Ten błąd jest podnoszony z wielu powodów, pomyślałem, rozwiązanie, które opublikowałem, może rozwiązać problem dla kogoś innego, jeśli powodem jest optymalizacja JIT.
curiousBoy,

6

Wpadłem i znalazłem dzisiaj rozwiązanie tego wyjątku. Występowało, gdy próbowałem debugować test jednostkowy (NUnit), który wywoływał metodę wirtualną w klasie abstrakcyjnej.

Wydaje się, że problem dotyczy instalacji .NET 4.5.1.

Pobrałem i zainstalowałem .NET 4.5.2 (moje projekty nadal odwołują się do .NET 4.5.1) i problem został rozwiązany.

Źródło rozwiązania:

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


5

Może to być sprzęt. Może to być coś skomplikowanego ... ale spróbowałbym zasugerować, że gdzieś twój kod wątków nie chroni jakiejś kolekcji (takiej jak słownik) za pomocą odpowiedniej blokady.

Jaki system operacyjny i dodatek Service Pack używasz?


1
Z systemem XP 64 SP2. Stało się to jednak na wielu serwerach. Przeszedłem przez wszystko tyle razy i nie widzę niczego, co nie jest bezpieczne. Czy nie otrzymywałbym raczej błędu zmodyfikowanego zbioru niż naruszenia zasad dostępu?
Ktoś inny

5

Miałem ten problem ostatnio, kiedy zmieniłem serwer deweloperski dla projektu. Otrzymałem ten błąd w wierszu kodu, w którym zadeklarowałem nową zmienną OracleConnection.

Po wypróbowaniu wielu rzeczy, w tym zainstalowaniu poprawek, próbowałem zmienić odniesienia Oracle.DataAccess i System.Data.OracleClient w projekcie i zadziałało!

Kiedy projekt jest przenoszony na nowy komputer, sugeruję odnowienie wszystkich odniesień dodanych w tym projekcie.


4

Czy próbowałeś wyłączyć DEP (zapobieganie wykonywaniu danych) dla swojej aplikacji?


2
Nie jestem pewien , czy to dobry pomysł. Może to opóźnić awarię, ale kosztem wyrządzenia większych szkód. Myślę, że najlepszym pomysłem, jeśli masz się rozbić, jest awaria wcześnie :-)
paxdiablo

1
Wyłączenie funkcji DEP jest nierozsądne, ale przydatne w diagnostyce.
vcsjones

4

Zmierzyłem się z tym samym problemem. Mój kod był biblioteką dll .NET (rozszerzenie AutoCAD) działającą w programie AutoCAD 2012. Używam również Oracle.DataAccess i mój kod zgłaszał ten sam wyjątek podczas wykonywania funkcji ExecuteNonQuery (). Na szczęście rozwiązałem ten problem, zmieniając wersję .net ODP, z którego korzystałem (czyli 2.x Oracle.DataAccess)


Mam do czynienia z tym samym problemem - autocad .net dll - czy możesz wyjaśnić, na czym polegał problem i go naprawić?
BKSpurgeon

3

Ta kwestia jest prawie zawsze prosta. Kod jest zły. Rzadko chodzi o narzędzia, tylko z analizy statystycznej. Niezliczone miliony ludzi używają programu Visual Studio każdego dnia, a może kilka z nich korzysta z Twojego kodu - który fragment kodu jest lepiej testowany? Gwarantuję, że gdyby to był problem z VS, prawdopodobnie już byśmy go znaleźli.

To stwierdzenie oznacza, że ​​kiedy próbujesz uzyskać dostęp do pamięci, która nie jest twoja, zwykle dzieje się tak dlatego, że robisz to z uszkodzonym wskaźnikiem, który pochodzi z innego miejsca. Dlatego podaje wskazanie.

W przypadku uszkodzenia pamięci wychwycenie błędu rzadko znajduje się w pobliżu głównej przyczyny błędu. A efekty są dokładnie takie, jakie opisujesz, pozornie przypadkowe. Musisz tylko przyjrzeć się zwykłym winowajcom, takim jak:

  • niezainicjowane wskaźniki lub inne wartości.
  • zapisywanie do bufora więcej niż jego rozmiaru.
  • zasoby współdzielone przez wątki, które nie są chronione przez muteksy.

Praca wstecz od problemu takiego jak ten w celu znalezienia przyczyny źródłowej jest niezwykle trudna, biorąc pod uwagę, że tak wiele mogło się wydarzyć między powstaniem problemu a wykryciem problemu.

Przeważnie uważam, że łatwiej jest przyjrzeć się temu, co jest uszkodzone (powiedzmy, konkretny wskaźnik), a następnie przeprowadzić ręczną analizę statyczną kodu, aby zobaczyć, co mogło go uszkodzić, sprawdzając zwykłe przyczyny, jak pokazano powyżej. Jednak nawet to nie spowoduje długich łańcuchów problemów.

Nie jestem wystarczająco zaznajomiony z VS, aby wiedzieć, ale możesz również przyjrzeć się możliwości użycia narzędzia do śledzenia pamięci (takiego jak Valgrind dla Linuksa), aby sprawdzić, czy może wykryć jakiekolwiek oczywiste problemy.


3
Możesz również uzyskać uszkodzony wskaźnik ze złej pamięci. Jeśli tak się nie dzieje na serwerze z pamięcią ECC, wypróbuj narzędzie do długotrwałego testowania pamięci, aby wyeliminować przyczynę sprzętu.
cdonner

12
Wiem, że to nie jest problem ze sprzętem, ponieważ występuje na wielu serwerach. Dzięki za wskazanie, że w kodzie kapitana jest coś złego. Nie winię Visual Studio. Jak stwierdzono, aplikacja działa poprawnie przez losowy okres czasu. Nie jest to łatwe do odtworzenia i od tygodni próbuję zidentyfikować problem.
Ktoś inny

5
@Someone Else: Nie sądzę, aby wyzwiska przyniosły ci dużą pomoc.
Mitch Wheat

2
@Kogoś jeszcze, pomogłem tak bardzo, jak tylko mogłem, biorąc pod uwagę ograniczone informacje, które podałeś. Nawet najlepszy lekarz na świecie nie może wiele zdziałać z pacjentem, który po prostu stwierdza: „Zraniłem” :-) Jeśli chciałbyś udzielić bardziej szczegółowych informacji, być może możemy więcej pomóc.
paxdiablo

5
Zła odpowiedź, ale podejście, bezwstydne spekulacje, nieuzasadnione założenia, brak rozwiązania ... Dlaczego ta odpowiedź jest wciąż aktualna? A jakie 3 osoby mogłyby zagłosować za tą odpowiedzią?
ThunderGr

3

Weryfikowalny kod nie powinien być w stanie uszkodzić pamięci, więc dzieje się coś niebezpiecznego. Czy używasz gdzieś niebezpiecznego kodu, na przykład podczas przetwarzania bufora? Ponadto informacje o PInvoke mogą nie być nieistotne, ponieważ PInvoke obejmuje przejście do niezarządzanego kodu i związane z nim organizowanie.

Moją najlepszą rekomendacją jest podłączenie się do zepsutej instancji i użycie WinDBG i SOS do dokładniejszego zbadania tego, co dzieje się w czasie awarii. To nie jest dla osób o słabym sercu, ale w tym momencie może być konieczne skorzystanie z potężniejszych narzędzi, aby określić, co dokładnie idzie nie tak.


Wspomina PInvoke jako możliwą przyczynę w komunikacie o błędzie. Nie ma niebezpiecznego kodu. Spróbuję WinDBG. Dzięki.
Ktoś inny

3

Ok, może to być całkiem bezużyteczne i po prostu anegdotyczne, ale ...

Ten wyjątek był konsekwentnie generowany przez niektóre biblioteki Twain32, których używaliśmy w moim projekcie, ale zdarzał się tylko na moim komputerze.

Próbowałem wielu sugerowanych rozwiązań w całym Internecie, ale bezskutecznie ... Dopóki nie odłączyłem telefonu komórkowego (był podłączony przez USB).

I zadziałało.

Okazuje się, że biblioteki Twain32 próbowały wyświetlić mój telefon jako urządzenie zgodne z Twain i coś, co zrobiło w tym procesie, spowodowało ten wyjątek.

Domyśl...


3

Wystąpił ten błąd podczas używania pinvoke w metodzie, która pobiera odwołanie do pliku StringBuilder . Użyłem domyślnego konstruktora, który najwyraźniej przydziela tylko 16 bajtów. Windows próbował umieścić więcej niż 16 bajtów w buforze i spowodował przepełnienie bufora.

Zamiast

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

Użyj większej pojemności:

StringBuilder windowText = new StringBuilder(3000);

2

w moim przypadku plik był otwarty i dlatego zablokowany.

Otrzymywałem to, próbując załadować plik Excela za pomocą LinqToExcel, który również został otwarty w Excelu.

to wszystko, co zrobiłem

    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);
    }

2

Ten sam błąd wystąpił w projekcie, z którym pracowałem w VB.NET. Zaznaczenie opcji „Włącz strukturę aplikacji” na stronie właściwości rozwiązało problem.


1

ja też miałem ten problem. W tym samym czasie pracowałem z różnymi rozwiązaniami, używając Visual Studio, kiedy zamykałem inne rozwiązania i uruchamiałem tylko rozwiązanie docelowe, działało dobrze bez tego błędu.


1

Ten błąd pojawia się losowo w VS1017 podczas próby zbudowania projektu, który budował się doskonale dzień wcześniej. Ponowne uruchomienie komputera rozwiązało problem (uruchomiłem również wcześniej następujące polecenie, nie jestem pewien, czy jest to wymagane: netsh winsock reset)


1
To jest dokładnie moja sytuacja z VS 2017 - System.AccessViolationException: Próbowano odczytać lub zapisać chronioną pamięć. Często wskazuje to na uszkodzenie innej pamięci. Po prostu zrestartowałem komputer, aby rozwiązać ten problem, nie robiąc nic innego.
Hong,

0

Moja odpowiedź bardzo zależy od twojego scenariusza, ale mieliśmy problem z próbą uaktualnienia aplikacji .NET dla klienta, który miał> 10 lat, aby mógł działać w systemie Windows 8.1. Odpowiedź @ alhazena była dla mnie odpowiednia. Aplikacja opierała się na bibliotece DLL innej firmy, za której aktualizację klient nie chciał płacić (Pegasus / Accusoft ImagXpress). Przekierowaliśmy aplikację na .NET 4.5, ale za każdym razem, gdy wykonywany był następujący wiersz, otrzymywaliśmy AccessViolationException was unhandledwiadomość:

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

Aby to naprawić, musieliśmy dodać do projektu następujące zdarzenie po kompilacji:

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

To jawnie określa plik wykonywalny jako niezgodny z funkcją zapobiegania wykonywaniu danych. Więcej informacji można znaleźć tutaj .


0

W niektórych przypadkach może się to zdarzyć, gdy:

obj = new obj();
...
obj.Dispose();  // <-----------------    Incorrect disposal causes it
obj.abc...

0

W moim przypadku musiałem odwołać się do biblioteki C / C ++ za pomocą P / Invoke, ale najpierw musiałem upewnić się, że pamięć została przydzielona dla tablicy wyjściowej za pomocą 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;
    }

Aby uzyskać szczegółowe informacje, zobacz: https://www.c-sharpcorner.com/article/pointers-in-C-Sharp/


0

Zdarzyło mi się to podczas debugowania mojej aplikacji C # WinForms w programie Visual Studio. Moja aplikacja wywołuje rzeczy Win32 poprzez DllImport, np

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

Uruchomienie programu Visual Studio „jako administrator” rozwiązało problem za mnie.


0

Miałem ten sam komunikat o błędzie:

System.AccessViolationException: próbowano odczytać lub zapisać chronioną pamięć. Często wskazuje to na uszkodzenie innej pamięci.

W moim przypadku błąd zniknął po wyczyszczeniu i ponownym skompilowaniu rozwiązania.


0

W moim przypadku narzędzie FTDI FT Prog wyrzucało błąd podczas skanowania w poszukiwaniu urządzeń USB. Odłączenie słuchawek Bluetooth od komputera rozwiązało problem.


0

Otrzymałem ten komunikat o błędzie w wyrażeniu lambda, które używało Linq do filtrowania kolekcji obiektów. Kiedy przejrzałem kolekcję, zauważyłem, że jej członkowie nie są zapełnieni - w Localsoknie rozwinięcie ich pokazało tylko „…”. Ostatecznie problem tkwił w metodzie repozytorium, która początkowo zapełniła kolekcję - Dapper próbował automatycznie odwzorować właściwość zagnieżdżonego obiektu. Naprawiłem zapytanie Dapper, aby obsłużyć multi-mapowanie, a to naprawiło błąd pamięci.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.