への呼び出しで終了する C# コンストラクターではthis(...)
、実際の呼び出しは次のように変換されます。
0000003d call dword ptr ds:[199B88E8h]
ここでの DS レジスタの内容は何ですか? データ セグメントであることはわかっていますが、この呼び出しは VMT テーブルなどを介したものですか? this(...)
ただし、仮想メソッドへの呼び出しではなく、単なる別のコンストラクターであるため、それは疑わしいです。
F11 キーを押して (Visual Studio 2008) にトレースすると、その呼び出し命令で、プログラムがアクセス違反でクラッシュします。
コードはサード パーティのコントロール ライブラリの奥深くにあります。ソース コードはありますが、C# コードを介してトレースできる十分なデバッグ情報を使用してコンパイルされたアセンブリがなく、逆アセンブラーのみを使用して、それを実際のコードに合わせます。
問題の C# コードは次のとおりです。
public AxisRangeData(AxisRange range) : this(range, range.Axis) {
}
Reflector には、次の IL コードが表示されます。
.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
失敗するのは、同じクラスの他のコンストラクターへの最後の呼び出しです。デバッガーが他のメソッド内に現れることはなく、クラッシュするだけです。
JITting 後のメソッドの逆アセンブリは次のとおりです。
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
基本的に私が求めているのはこれです:
ds:[ADDR]
ここでの間接化の目的は何ですか? VMT-tableは仮想専用ですよね?そしてこれはコンストラクタです- コンストラクターはまだ JIT されていない可能性があります。これは、呼び出しが実際に JIT shim を介して呼び出されることを意味する可能性がありますか? 私はここで深海にいるのではないかと心配しているので、何でも役立つかもしれません.
編集:まあ、問題は悪化したか、改善したか、または何でも。
Visual Studio 2008 ソリューションの C# プロジェクトで .NET 機能を開発し、Visual Studio を使用してデバッグと開発を行っています。
ただし、最終的に、このコードは Win32 Delphi アプリケーションによってホストされる .NET ランタイムにロードされます。
このような機能を簡単に実験できるようにするために、Visual Studio プロジェクト/ソリューション/デバッガーを構成して、生成された dll を Delphi アプリのディレクトリにコピーし、Visual Studio デバッガーを介して Delphi アプリを実行することもできます。
デバッガーの外でプログラムを実行すると問題は解決しますが、デバッグ中に毎回問題が発生します。
それが役立つかどうかはわかりませんが、コードの本番リリースはあと 6 か月ほど予定されていないため、間もなく行われるテスト リリースに対するプレッシャーが軽減されます。
後でメモリの部分に飛び込みますが、おそらく週末になるまでは続かないので、フォローアップを投稿します.