在C#构造函数中,如果最终调用了
这里的DS寄存器内容是什么?我知道它是数据段,但这是通过VMT表或类似方式调用的吗?我怀疑不是,因为
我问这个问题是因为该位置的值在某种程度上似乎有问题,如果我按F11,跟踪(Visual Studio 2008)该调用指令,程序将崩溃并显示访问冲突。
代码深入到第三方控件库中,虽然我有源代码,但我没有编译足够调试信息的程序集,所以只能通过反汇编器进行跟踪,然后将其与实际代码匹配。
涉及的C#代码如下:
this(...)
,那么实际调用会被转换为以下内容:0000003d call dword ptr ds:[199B88E8h]
这里的DS寄存器内容是什么?我知道它是数据段,但这是通过VMT表或类似方式调用的吗?我怀疑不是,因为
this(...)
不会是对虚拟方法的调用,只是另一个构造函数。我问这个问题是因为该位置的值在某种程度上似乎有问题,如果我按F11,跟踪(Visual Studio 2008)该调用指令,程序将崩溃并显示访问冲突。
代码深入到第三方控件库中,虽然我有源代码,但我没有编译足够调试信息的程序集,所以只能通过反汇编器进行跟踪,然后将其与实际代码匹配。
涉及的C#代码如下:
public AxisRangeData(AxisRange range) : this(range, range.Axis) {
}
反射器向我展示了这段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
这里是最后一次调用同一个类的另一个构造函数失败了。调试器从未进入另一个方法,它只是崩溃了。
JIT编译后该方法的反汇编代码如下:
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表只用于虚拟,这是构造函数- 构造函数可能尚未被JIT编译,这是否意味着调用实际上会通过JIT shim调用?我有点无助,任何信息都可能有所帮助。
编辑:好吧,问题变得更糟了,或者更好了,或者不管怎样。
我们在Visual Studio 2008解决方案的C#项目中开发.NET功能,并通过Visual Studio进行调试和开发。
然而,最终,这段代码将加载到由Win32 Delphi应用程序托管的.NET运行时中。
为了方便对这些功能进行实验,我们还可以配置Visual Studio项目/解决方案/调试器,将生成的dll复制到Delphi应用程序目录中,然后通过Visual Studio调试器执行Delphi应用程序。
事实证明,如果我在调试器之外运行程序,问题就会消失,但是在调试期间,它每次都会出现。
不确定这是否有帮助,但由于该代码距离预计的生产发布还有大约6个月左右,因此在即将到来的测试发布中,它可以减轻一些压力。
我稍后会深入研究内存部分,但可能要等到周末才行,并发布跟进结果。