2009-04-23 2 views
4

, 즉 실제 호출이로 번역됩니다, this(...)에 전화로 끝 .NET JITted 코드에서 어셈블러 코드 줄을 해독 도움을 필요 DS 등록 내용은 여기에 있습니까? 나는 그것이 데이터 세그먼트라는 것을 알고 있지만, VMT 테이블이나 비슷한 것을 통해이 호출을 할 수 있습니까? 나는 그것이 의심 스럽지만, this(...)은 가상 메소드에 대한 호출이 아니며 다른 생성자로만 호출됩니다.C#을 생성자에서

그 위치의 값이 어떤 식 으로든 나빠 보이기 때문에 F11을 누르면 (Visual Studio 2008), 해당 호출 명령에서 프로그램이 액세스 위반으로 충돌합니다.

코드는 제 3 자 컨트롤 라이브러리의 깊숙한 곳에 있습니다. 소스 코드가 있지만 어셈블리어를 통해 C# 코드를 통해 추적 할 수있는 충분한 디버그 정보가있는 어셈블리가 없습니다. 그런 다음 실제 코드와 다시 일치시켜야합니다.

public AxisRangeData(AxisRange range) : this(range, range.Axis) { 
} 

반사경이 나에게이 IL 코드를 보여줍니다 :

문제의 C# 코드는 이것이다

.maxstack 8 
L_0000: ldarg.0 
L_0001: ldarg.1 
L_0002: ldarg.1 
L_0003: callvirt instance class DevExpress.XtraCharts.AxisBase DevExpress.XtraCharts.AxisRange::get_Axis() 
L_0008: call instance void DevExpress.XtraCharts.Native.AxisRangeData::.ctor(class DevExpress.XtraCharts.ChartElement, class DevExpress.XtraCharts.AxisBase) 
L_000d: ret 

그것은 마지막 통화가 같은 클래스의 다른 생성자에,있다, 즉 실패 . 디버거는 다른 메소드 내부에 절대 놓이지 않습니다. 충돌합니다.

00000000 push  ebp 
00000001 mov   ebp,esp 
00000003 sub   esp,14h 
00000006 mov   dword ptr [ebp-4],ecx 
00000009 mov   dword ptr [ebp-8],edx 
0000000c cmp   dword ptr ds:[18890E24h],0 
00000013 je   0000001A 
00000015 call  61843511 
0000001a mov   eax,dword ptr [ebp-4] 
0000001d mov   dword ptr [ebp-0Ch],eax 
00000020 mov   eax,dword ptr [ebp-8] 
00000023 mov   dword ptr [ebp-10h],eax 
00000026 mov   ecx,dword ptr [ebp-8] 
00000029 cmp   dword ptr [ecx],ecx 
0000002b call  dword ptr ds:[1889D0DCh] // range.Axis 
00000031 mov   dword ptr [ebp-14h],eax 
00000034 push  dword ptr [ebp-14h] 
00000037 mov   edx,dword ptr [ebp-10h] 
0000003a mov   ecx,dword ptr [ebp-0Ch] 
0000003d call  dword ptr ds:[199B88E8h] // this(range, range.Axis)? 
00000043 nop    
00000044 mov   esp,ebp 
00000046 pop   ebp 
00000047 ret    

기본적으로 내가 부탁 해요 것은 이것이다 :

JITting 후 메소드의 분해는 이것이다

  • 무엇 여기 ds:[ADDR] 간접의 목적? VMT 테이블은 가상 전용입니다. 그리고 이것은 생성자입니다
  • 생성자가 아직 JIT 화되어 있어야 호출이 실제로 JIT 심을 호출 할 수 있습니까? 나는 여기 물이 깊어서 무엇이라도 도움이 될 수 있다고 생각합니다.

편집 : 음, 문제는 단지 더 나쁜, 또는 더 나은, 또는 무엇이든을 얻었다.

우리는 Visual Studio 2008 솔루션의 C# 프로젝트에서 .NET 기능을 개발하고 Visual Studio를 통해 디버깅 및 개발하고 있습니다.

그러나 결국이 코드는 Win32 Delphi 응용 프로그램에서 호스팅되는 .NET 런타임에로드됩니다.

이러한 기능을 쉽게 실험 할 수 있도록 Visual Studio 프로젝트/솔루션/디버거에서 생성 된 dll 파일을 Delphi 앱 디렉토리로 복사 한 다음 Visual Studio 디버거를 통해 Delphi 앱을 실행하도록 구성 할 수도 있습니다.

디버거 외부에서 프로그램을 실행하면 문제가 해결되지만 디버깅 중에는 항상 문제가 발생합니다.

코드가 도움이되는지 확실하지 않지만 코드가 6 개월 정도 동안 프로덕션 릴리스로 예정되지 않았으므로 곧 출시 될 테스트 릴리스에 대한 압력이 줄어 듭니다.

나중에 메모리 파트로 다이빙 하겠지만 주말까지는 그렇지 않을 것이므로 추가 작업을 게시하십시오.

+0

ds : [199B88E8h]가 실제로 가리키는 주소를 찾아서 디스 어셈블 할 수 있습니까? – Groo

+0

주소에 저장되어있는 주소이며 매핑되지 않은 메모리를 가리키는 주소이므로 액세스 위반입니다. –

답변

3

데이터 세그먼트는 일반적으로 컴파일러가 전역 변수를 넣고 가져 오기 주소 테이블이있는 곳입니다.

00000029 cmp   dword ptr [ecx],ecx 
0000002b call  dword ptr ds:[1889D0DCh] 

첫 번째 줄은 ECX 레지스터에있는 포인터가 유효하지 않은 경우 결국 NullReferenceException을 제기 널 검사는, 실제로.

callvirt MSIL 명령어는 실제 메소드를 호출하기 전에 Null 검사를 수행해야합니다.

class DevExpress.XtraCharts.AxisBase DevExpress.XtraCharts.AxisRange::get_Axis() 

그리고 주석 어셈블리 코드 : 그건 우리가 안전하게 어셈블리 코드의 두 라인은 다음 MSIL 코드 표현이 있다고 가정 할 수 있습니다 말했다되고

00000026 mov   ecx,dword ptr [ebp-8]  // store the pointer to the 'range' in ECX 
00000029 cmp   dword ptr [ecx],ecx  // null-check 
0000002b call  dword ptr ds:[1889D0DCh] // range.get_Axis() 
00000031 mov   dword ptr [ebp-14h],eax // store the result in a local variable 
00000034 push  dword ptr [ebp-14h]  // push the result onto a stack 
00000037 mov   edx,dword ptr [ebp-10h] // this variable was previously loaded with the 'range' pointer 
0000003a mov   ecx,dword ptr [ebp-0Ch] // here seems to be stored the actual 'this' pointer 
0000003d call  dword ptr ds:[199B88E8h] // call the this(...) ctor 

이 충돌 왜 그것은 나에게 불분명, 메모리 위치 (DS:[199B88E8h])의 내용을 찾으려고 했습니까?

+0

예, 다양한 통화 안내에서 볼 수있는 값을 내일 게시 해 드리겠습니다. 그것이 다른 사람과 비교하여 이상하게 보일 정도로 충분합니다 (이 시점까지 각 통화 지시를 중단했습니다). 오류가있는 것은 첫 번째 숫자가 0이 아닌 유일한 것입니다. –

관련 문제