In a C # constructor that ends with a call to this(...) , the actual call translates to this:
0000003d call dword ptr ds:[199B88E8h]
What is the contents of the DS register here? I know this is a data segment, but is it a call through a VMT table or the like? I doubt it, however, since this(...) would not be a call to a virtual method, just another constructor.
I ask, because the value in this place is apparently bad in some way, if I find F11, trace in (Visual Studio 2008), in this call command, the program crashes with an access violation.
The code is deep inside a third-party management library, where although I have the source code, I do not have assemblies compiled with enough debugging information that I can trace through C # code only through a disassembler and then I have to match this with the real code.
C # code requested:
public AxisRangeData(AxisRange range) : this(range, range.Axis) { }
Reflector shows me this IL code:
.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
This is the last call there, to another constructor of the same class that fails. The debugger never encounters another method, it just crashes.
The disassembly for the method after JITting is this:
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
I basically ask:
- What is the purpose of
ds:[ADDR] indirection here? A VMT table is only for virtual ones, right? and this is the constructor - Could the constructor still be JITted, which could mean that the call will actually cause a JIT pad? I'm afraid I'm here in deep water, so everything could and could help.
Change Well, the problem has only worsened, or better, or something else.
We are developing a .NET function in a C # project in Visual Studio 2008, and we are also debugging and developing through Visual Studio.
However, in the end, this code will be loaded into the .NET runtime hosted by the Win32 Delphi application.
To facilitate experiments with such functions, we can also set up a Visual Studio project / solution / debugger to copy the created DLL to the Delphi application directory and then run the Delphi application through the Visual Studio debugger.
It turns out that the problem disappears if I run the program outside the debugger, but during debugging it appears every time.
I’m not sure if this helps, but since the code is not planned to release products for another 6 months or so, some pressure is required to remove the test release.
Later, I will dive into parts of the memory, but probably not earlier than on the weekend, and will publish the following description.