В конструкторе 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) {
}
Отражатель показывает мне этот код 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-таблица только для виртуальных, не так ли? и это конструктор
- Может ли конструктор еще быть JITted, что может означать, что вызов действительно будет вызываться через прокладку JIT? Боюсь, что я в глубокой воде, поэтому все может и может помочь.
Редактировать : Ну, проблема только усугубилась, или улучшилась, или как там.
Мы разрабатываем функцию .NET в проекте C # в решении Visual Studio 2008, а также отлаживаем и разрабатываем с помощью Visual Studio.
Однако, в конце концов, этот код будет загружен в среду выполнения .NET, размещенную приложением Win32 Delphi.
Чтобы упростить экспериментирование с такими функциями, мы также можем настроить проект / решение / отладчик Visual Studio для копирования созданных библиотек DLL в каталог приложения Delphi, а затем запустить приложение Delphi через отладчик Visual Studio.
Оказывается, проблема исчезает, если я запускаю программу вне отладчика, но во время отладки она возникает каждый раз.
Не уверен, что это помогает, но, поскольку код не планируется к выпуску в течение еще 6 месяцев или около того, он снимает с него некоторое давление для тестового выпуска, который у нас скоро.
Я углублюсь в детали памяти позже, но, вероятно, не раньше, чем в выходные, и выложу продолжение.