디버깅 시스템.AccessViolationException-DllImport 지옥
System.AccessViolationException
.비 트랜잭션 코드가 할당되지 않은 메모리에서 읽거나 쓰기를 시도할 때 보통 이상이 발생합니다.오류 처리
이상을 포착하는 것이 항상 네가 상상하는 것처럼 그렇게 쉬운 것은 아니다.
System.AccessViolationException
을 쉽게 처리할 수 있는 예시부터 시작합시다.다음 절차에 따라 예외가 발생하고 캡처됩니다.class Program
{
static void Main(string[] args)
{
try
{
var intPtr = new IntPtr(1);
Marshal.WriteByte(intPtr, 1);
}
catch (AccessViolationException e)
{
Console.WriteLine(e);
}
}
}
이 예에서 WriteByte
방법은 새로운 System.AccessViolationException
을 던졌다.예외를 포착하려면 일반적인 C# 배치 블록만 필요합니다.예외는 일반적으로 다음과 같은 상당히 일반적인 오류 메시지를 발생시킵니다.Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
대부분의 경우 (적어도 내 경험에서)
AccessViolationException
을 사용하여 C++ 코드를 호출할 때 DllImport
을 던진다.나는 하나를 만든 것을 기억한다.NET 프로그램, 오래된 C++API를 통해 코드를 휴대전화에 연결합니다.코드는 어느 정도에 비 트랜잭션 코드에서 호출하는 방법에 의존하고 AccessViolationException
을 처리하는 것은 프로그램 작성에 필요한 일부분이다.나는 이것이 바로 네가 낡은 오류 코드와 통합하려고 시도한 것에서 얻은 것이라고 생각한다. D이것은 확실히
DllImport
을 사용하여 이상을 다시 만들었습니다. 저는 다음과 같은 결함이 있는 C++ 코드를 작성했습니다.#include "pch.h"
#include "Violator.h"
void ViolateMe()
{
int* data1 = 0;
*data1 = 0;
}
Visual Studio 2019는 코드를 생성할 때 경고를 생성합니다.6011: Dereferencing NULL pointer 'data1'.
C#에서 호출하려면 다음 코드를 사용합니다.
class Program
{
static void Main(string[] args)
{
try
{
ViolateMe();
}
catch (AccessViolationException e)
{
Console.WriteLine(e);
}
}
[DllImport(@"C:\path\to\ViolatorLib.dll")]
private static extern int ViolateMe();
}
코드를 실행할 때, 실제로는 AccessViolationException
을 던졌지만, 우리의catch 블로그는 클릭되지 않았다.이 점을 실현할 수 있는 여러 가지 방법이 있다.하나는 다음과 같은 방법으로 HandleProcessCorruptedStateExceptionsAttribute
속성을 추가하는 것입니다.class Program
{
[HandleProcessCorruptedStateExceptions]
static void Main(string[] args)
{
// ...
}
// ...
}
[HandleProcessCorruptedStateExceptions]
을 Main
방법에 추가하면 캐치블로그의 실제 포획 이상을 초래할 수 있습니다.또 다른 방법은 legacyCorruptedStateExceptionsPolicy
에서 app/web.config
을 true로 설정하는 것입니다.<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>
...
</configuration>
마이크로소프트는 그 설정을 추가하지 말라고 건의한 것 같지만, 나는 결코 정말로 동의하지 않는다.그들이 이렇게 하는 이유는 사실상 심각한 오류이기 때문에 응용 프로그램이 닫힐 수 있기 때문이다.하지만 사용자에게 무슨 나쁜 일이 일어났는지 알려주고 오류 로그에 이상을 기록하려고 합니다.... 에 이르다NET 코어 중
HandleProcessCorruptedStateExceptionsAttribute
은 프레임에 있지만 AccessViolationException
을 포획하지는 않을 것 같습니다.나는 사람들의 이 방면의 경험을 매우 듣고 싶다.순수한 핵심.디버그 오류
솔직히
AccessViolationException
은 디버깅의 악몽일 수도 있다.대부분의 경우, 오류는 접근할 권리가 없는 비 트랜잭션 코드에서 발생합니다.우리는 서로 다른 장면을 깊이 연구하고 어떻게 모든 상황에서 이상을 위협하는지 토론합시다.관리되지 않는 코드에 접근할 수 있을 때
위의 예를 계속합시다.이런 상황에서 나는 실패한 C++ 코드에 접근할 수 있다.F11을 사용하여
ValidateMe
메서드에 들어가면 Visual Studio가 C++ 코드를 건너뛰고 catch
블록으로 바로 이동하는 것을 알 수 있습니다.이것은 기본적으로 본 컴퓨터의 코드 디버깅을 사용하지 않았기 때문이다.이 문제를 해결하려면 C# 항목을 마우스 오른쪽 버튼으로 클릭하고 속성을 클릭한 다음 디버그 탭을 선택합니다.다음 디버거 엔진에서 [기본 코드 디버그 활성화] 를 선택하거나 Ctrl +t 를 클릭하십시오.프로젝트를 저장하고 응용 프로그램을 시작하면 Visual Studio가 C++ 코드에서 중단됩니다.이 오류를 초래한 정확한 줄과 변수를 볼 수 있는 것은 큰 도움이 된다.
관리되지 않는 코드에 접근할 수 없을 때
자식.실패한 코드에 접근할 수 없기 때문에 계속 읽고 있죠?이런 상황에서 코드에 연락하는 관리자 외에는 할 일이 없다.그들을 돕기 위해서 프로그램의 메모리 덤프를 생성할 수 있습니다.이렇게 하려면 Visual Studio를 통해 응용 프로그램을 실행하고 예외가 발생할 때까지 기다리십시오.그런 다음 디버그 | 덤프를 다른 이름으로 저장...파일의 이름을 지정합니다.위탁 코드가 아닌 개발자는 WinDbg 같은 도구를 사용하여 무슨 일이 일어났는지 시도하고 찾아낼 수 있다.
제가 WinDbg를 언급했으니까 "왜 WinDbg 사용에 문제가 있는지 스스로 검사하지 않으십니까?"좋은 질문.이것은 절대로 가능하다.WinDbg는 확실히 나를 위해 한두 번의 시간을 절약해 주었다.WinDbg를 사용하는 것은 일반 사용자에게 필요한 기술과는 거리가 멀다.NET 개발자.만약 보편적인 수요가 있다면, 나는 몇 가지 물건을 쓸 것이다.이제 Visual Studio를 사용하여 프로세스 메모리 덤프를 만들 수 있다는 것만 알면 됩니다.
WebBrowser 컨트롤을 사용할 때
Windows 창과 WPF에는
WebBrowser
이라고 간단하게 불리는 웹 브라우저 구성 요소가 묶여 있습니다.나는 AccessViolationException
을 겪었고, 많은 사람들이 이런 상황에서 이 이상을 불평하는 것을 보았다.브라우저 구성 요소는 과거에 상당히 결함이 있었다.최근 몇 년 동안, 나는 대다수의 문제가 모두 라인 문제로 인해 일어난 것이라고 생각한다.C 언어의 웹 컨트롤은 일반적으로 URL의 헤더 없는 스냅샷을 생성하는 데 사용됩니다.내 말은, 요 며칠 동안 당신들은 삽입식 브라우저 기능을 갖춘 Windows 창 응용 프로그램을 얼마나 생산했습니까?
스레드에서
WebBrowser
컨트롤을 만들 때 스레드에 올바른 ApartmentState
을 설정하십시오.var thread = new Thread(() =>
{
var br = new WebBrowser();
br.Navigate(url);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
STA 상태는 ActiveX 구성 요소(예: WebBrowser
)를 실행하는 유일한 유효한 방법입니다.대체 방안으로 [STAThread]
속성 장식 라인을 호출하는 방법을 사용할 수 있습니다.IIS 내부 AccessViolationException
나는 IIS에서 이런 이상을 겪은 적이 없지만, 누군가가 이 문제를 물어본 것을 보았다.이곳의 전형적인 해결 방안은 당신이 최신 버전을 실행하는 것을 확보하는 것이다.순액
웹 브라우저 컨트롤의 예시와 같이 WinDbg와 유사한 도구를 아는 사람에게 메모리를 저장하면 이 오류를 디버깅하는 데 도움을 줄 수 있습니다.실행 중인 IIS 프로세스에서 메모리 덤프를 만들기 위해서는 응용 프로그램을 실행하는 응용 프로그램 풀의 작업 관리자에서
w3wp.exe
프로세스를 찾아야 합니다.찾은 후 프로세스를 마우스 오른쪽 버튼으로 클릭하고 덤프 파일 만들기 메뉴 항목을 선택합니다.그렇습니다!대량의 요구가 없으면, 이것은common 디버깅에 관한 마지막 문장이 될 것이다.순전히 예외다.여기 있는 모든 게시물 목록 보기: Debugging common .NET exceptions.
사용자가 더 적은 오류를 원하십니까?
엘마.io는 간단한 오류 기록과 정상적인 운행 시간 감시 서비스입니다.순액모든 사람에 대한 지원을 통해 오류를 다시 제어합니다.NET 웹 및 로그 프레임워크
➡️ Error Monitoring for .NET Web Applications⬅️
이 문장은 먼저 《elmah》에 나타났다.io 블로그 https://blog.elmah.io/debugging-system-accessviolationexception/
Reference
이 문제에 관하여(디버깅 시스템.AccessViolationException-DllImport 지옥), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thomasardal/debugging-system-accessviolationexception-dllimport-hell-4j4c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)