2014-01-13 4 views
12

우리는 System.Reflection.Emit을 사용하여 런타임에 소스 코드에서 코드를 생성합니다 (예 - 컴파일러 에서처럼). 우리는 MarkSequencePoint 등을 사용하여 ILGenerator에 올바른 심볼 정보를 제공하고 AssemblyBuilder에서 모든 디버그 플래그를 활성화합니다. 어셈블리는 컴파일 된 동일한 프로세스에서 메모리에 보관되며 직접 실행됩니다.동적 코드의 예외 스택 추적에서 잘못된 파일 경로 및 줄 번호

Visual Studio 디버거를 사용하여 동적으로 생성 된 코드의 소스를 단계별로 실행할 때 실제로 완벽하게 작동하며 Visual Studio는 코드가 파일 및 행 번호와 관련하여 어디에서 비롯되는지 완전히 인식하는 것 같습니다.

- 그러나, 완전히 잘못 예외생성 된 코드에 의해 발생되는 경우, System.Exception 개체 스택 포함 흔적. 그들은 다른 (유효하지만 잘못된) 파일과 행 번호를 가리 킵니다. 클래스와 메소드 이름을 올바르게 가져 오지만, 가리키는 파일과 라인 번호는 실제로 예외가 발생한 코드 경로와 아무런 관련이 없습니다.

가리키는 파일이 너무 관련이 없기 때문에 인라인 또는 최적화에 연결할 수없는 것 같습니다. 내가 발견 할 수있는 유일한 패턴은 일부 파일 (어셈블리가 빌드 된 소스 파일의 알파벳순 정렬 목록)에서 오프셋 된 것으로 보입니다. 그러나이 패턴은 100 % 일관성이 없으며 이것이 문제의 원인과 관련이 있다고 보입니다.

Exception에서 System.Diagnostics.Debug 개체를 구성하면 동일한 오류 정보가 포함됩니다.

.NET 런타임에서 디버거가 코드를 단계별로 실행하기 위해 사용하는 Exception 스택 추적을 위해 동일한 메타 데이터를 사용한다고 가정합니다.이 경우에는이 동작이 실제로 이상합니다.

동적 인 메모리 어셈블리를 처리 할 때 .NET의 알려진 버그인지 또는 다른 영역에서 유사한 문제가 발생했는지 확인하려고합니다.

+5

테스트 할 수있는 작고 완전한 프로그램을 게시 할 수 있습니까?예를 들어 두 줄의 "언어"또는 그와 비슷한 것을 하드 코딩 할 수 있습니다. 전체 컴파일러를 게시 할 필요는 없습니다. –

+1

'optimize' 플래그로 컴파일하고 있습니까? – Andrew

+0

Andrew : 컴파일러 또는 assemblybuilder에서? 나는 가능한 한 많은 디버그 정보를 원한다. 가능한 많은 플래그를 설정하려고 시도했지만, 나는 그것들을 모두 알지 못할 수도있다. – Duckers

답변

1

그래, 문제의 원인이 무엇인지, .NET을 올바르게 작동시키는 방법을 알아낼 수는 없었지만 적어도 동일한 문제를 겪고있는 다른 사람들을 위해 해결할 수있는 해결 방법을 찾을 수있었습니다.

  1. 나는 CIL 바이트 코드 나 메소드 이름 (전체 경로) 및 원본 파일 이름과 줄 번호로 다시 IL은 오프셋을 매핑하는 별도의 데이터베이스를 구축하고 발생하고있다.

  2. 예외가 발견되면 스택 추적을 검사하고 스택 프레임 개체의 정보 인 GetMethod()GetILOffset() 만 사용하십시오. GetFileName()GetFileLineNumber()이 잘못된 경우에도 CLR의이 정보가 정확합니다.

  3. 다음 각 스택 프레임에 대해 예외에서 검색 한 메서드 이름과 IL 오프셋을 사용하여 생성 된 데이터베이스를 조회하여 정보가있는 각 스택 프레임의 실제 파일 이름과 줄 번호를 확인합니다.

  4. 데이터베이스에서 정보를 찾을 수없는 프레임은 일반적으로 CLR에서 검색 한 정보가 실제로 올바른 미리 컴파일 된 .NET 모듈의 스택 프레임입니다. 이 프레임의 경우 스택 프레임에 GetFileName()GetFileLineNumber()을 직접 사용합니다.

관련 문제