Dans un constructeur C#, qui se termine par un appel à this(...)
, l'appel réel se traduit à ceci:Besoin d'aide pour déchiffrer une ligne de code assembleur, à partir du code .NET JITted
0000003d call dword ptr ds:[199B88E8h]
Quelle est la DS enregistrer le contenu ici? Je sais que c'est le segment de données, mais cet appel est-il à travers une table VMT ou similaire? J'en doute cependant, car this(...)
ne serait pas un appel à une méthode virtuelle, juste un autre constructeur. Je demande parce que la valeur à cet endroit semble être mauvaise d'une certaine façon, si je tape F11, trace dans (Visual Studio 2008), sur cette instruction d'appel, le programme se bloque avec une violation d'accès. Le code est au fond d'une bibliothèque de contrôle tierce, où, bien que j'ai le code source, je n'ai pas les assemblies compilées avec assez d'informations de débogage que je peux tracer à travers le code C#, seulement par le désassembleur, et puis je dois faire correspondre cela au code réel.
Le code C# en question est la suivante:
public AxisRangeData(AxisRange range) : this(range, range.Axis) {
}
réflecteur me montre ce code 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
Il est que le dernier Appel, à l'autre constructeur de la même classe, qui échoue . Le débogueur ne surface jamais dans l'autre méthode, il se bloque juste.
Le démontage de la méthode après JITting est la suivante:
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
Fondamentalement, ce que je pose est la suivante:
- Ce que le but de la
ds:[ADDR]
indirection ici? VMT-table est seulement pour le virtuel n'est-ce pas? et ceci est le constructeur - Le constructeur pourrait-il encore être JITted, ce qui pourrait signifier que l'appel ferait appel à un shim JIT? J'ai peur que je sois dans l'eau profonde ici, donc tout pourrait et pourrait aider.
Modifier: Eh bien, le problème ne faisait qu'empirer, ou mieux, ou autre chose.
Nous développons la fonctionnalité .NET dans un projet C# dans une solution Visual Studio 2008, ainsi que le débogage et le développement via Visual Studio. Toutefois, à la fin, ce code sera chargé dans un environnement d'exécution .NET hébergé par une application Delphi Win32. Pour faciliter l'expérimentation de telles fonctionnalités, nous pouvons également configurer le projet/solution/débogueur Visual Studio pour copier les DLL produites dans le répertoire de l'application Delphi, puis exécuter l'application Delphi via le débogueur Visual Studio.
Il s'avère que le problème disparaît si j'exécute le programme en dehors du débogueur, mais lors du débogage, il apparaît à chaque fois.
Pas sûr que cela aide, mais puisque le code n'est pas prévu pour la sortie de production pour un autre 6 mois ou plus, alors il enlève une partie de la pression pour la version de test que nous avons bientôt.
Je vais plonger dans les parties de la mémoire plus tard, mais probablement pas avant le week-end, et poster un suivi.
Pouvez-vous trouver l'adresse réellement pointée par ds: [199B88E8h] et la désassembler? – Groo
C'est une adresse stockée à cet endroit, et cette adresse pointe vers la mémoire non mappée, d'où la violation d'accès. –