En utilisant Windbg/SOS, est-il possible de changer la valeur d'une variable locale sur la pile? Si c'est le cas, comment?changer la valeur de la pile locale
Répondre
La réponse courte est: Cela dépend.
Par défaut, les types de valeur locale sont stockés sur la pile, mais en raison de l'optimisation, ils seront souvent stockés uniquement dans des registres si nécessaire. Les types de références sont stockés sur le tas, avec une référence à l'instance sur la pile (ou dans un registre). Je vais supposer que vous cherchez à changer un type de valeur locale. Regardons un exemple simple.
[MethodImpl(MethodImplOptions.NoInlining)] // avoid inlining of short method
public static void Method(int x) {
Console.WriteLine("The answer is {0}", x + x);
}
En supposant que nous fixons un point d'arrêt sur Method
et exécuter jusqu'à ce que le point de rupture est atteint, la pile ressemble à ceci:
0:000> !clrstack -a
OS Thread Id: 0x1abc (0)
Child SP IP Call Site
0035f290 003600e0 TestBench2010.Program.Method(Int32)*** WARNING: Unable to verify checksum for C:\workspaces\TestBench2010\TestBench2010\bin\Release\TestBench2010.exe
[C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 17]
PARAMETERS:
x (<CLR reg>) = 0x00000002
0035f294 003600a2 TestBench2010.Program.Main(System.String[]) [C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 24]
PARAMETERS:
args = <no data>
0035f4c0 636221bb [GCFrame: 0035f4c0]
Notez que la x
locale est répertorié comme, mais il ne dit pas nous qui registre. Nous pourrions regarder les registres et trouver celui avec la valeur 2, mais il pourrait y en avoir plus d'un. Au lieu de cela, regardons le code compilé JIT pour la méthode.
0:000> !u 001c37f0
Normal JIT generated code
TestBench2010.Program.Method(Int32)
Begin 003600e0, size 32
C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 17:
003600e0 55 push ebp
003600e1 8bec mov ebp,esp
003600e3 56 push esi
003600e4 8bf1 mov esi,ecx
*** WARNING: Unable to verify checksum for C:\windows\assembly\NativeImages_v4.0.30319_32\mscorlib\658bbc023e2f4f4e802be9483e988373\mscorlib.ni.dll
003600e6 b9302be004 mov ecx,offset mscorlib_ni+0x322b30 (04e02b30) (MT: System.Int32)
003600eb e8301fe5ff call 001b2020 (JitHelp: CORINFO_HELP_NEWSFAST)
003600f0 8bd0 mov edx,eax
003600f2 03f6 add esi,esi <==== This is x + x
003600f4 897204 mov dword ptr [edx+4],esi
003600f7 8bf2 mov esi,edx
003600f9 e882709d04 call mscorlib_ni+0x257180 (04d37180)(System.Console.get_Out(), mdToken: 060008cd)
003600fe 56 push esi
003600ff 8bc8 mov ecx,eax
00360101 8b1534204c03 mov edx,dword ptr ds:[34C2034h] ("The answer is {0}")
00360107 8b01 mov eax,dword ptr [ecx]
00360109 8b403c mov eax,dword ptr [eax+3Ch]
0036010c ff5018 call dword ptr [eax+18h]
C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 18:
0036010f 5e pop esi
00360110 5d pop ebp
00360111 c3 ret
En regardant le code, nous voyons que la seule instruction add
utilise le registre esi
, notre valeur est stockée ici avant le calcul. Malheureusement, esi
ne détient pas la valeur correcte à ce stade, mais en regardant en arrière, nous trouvons mov esi,ecx
. C'est à dire. la valeur est initialement stockée dans ecx
.
Pour modifier la valeur de ecx
, utilisez la commande r
. Par exemple. pour définir la valeur à 0x15 effectuer les opérations suivantes:
0:000> r ecx=15
La sortie de la méthode est maintenant:
La réponse est 42
S'il vous plaît garder à l'esprit que l'exemple ci-dessus est seulement un des nombreux scénarios possibles. Les sections locales sont traitées différemment en fonction de la version de débogage/lancement ainsi qu'en 32/64 bits. En outre, pour les méthodes complexes, il peut être un peu plus difficile de suivre l'emplacement exact de la valeur. Pour changer l'état d'une instance, vous devez localiser la référence sur la pile (par exemple, en utilisant !clrstack
ou !dso
). Une fois localisé, vous pouvez utiliser les décalages pour trouver la mémoire qui contient les données et utiliser les commandes e*
pour modifier les valeurs si nécessaire. Faites-moi savoir si vous voulez un exemple pour cela aussi.
- 1. enregistrement d'étendue locale sur la pile
- 2. Assemblage, opération arithmétique sur une variable locale sur la pile
- 3. Comment changer la valeur
- 4. PHP Changer la fin de la valeur?
- 5. Impossible de stocker la valeur dans la pile
- 6. retourner la valeur dans une pile - C++
- 7. Pointeur passant: valeur différente dans la pile?
- 8. Comment changer la valeur de la valeur dans BASH?
- 9. Comment changer l'image de la base locale dans magento?
- 10. Comment changer le nom du son de la notification locale?
- 11. Comment changer la variable de classe locale IBAction
- 12. Connaître la taille de la pile d'événements
- 13. Struts2 - Nécessité de changer la valeur de l'élément de style de <s: textfield dynamiquement en utilisant la variable locale
- 14. SortedDictionary (C#) - changer la valeur
- 15. Variable mystérieusement changer la valeur
- 16. Comment changer la propriété d'un widget GTK comme une pile?
- 17. La variable locale de type string est stockée sur la pile ou le tas?
- 18. Limite de la pile gcc
- 19. JSF Converter changer la valeur de l'option
- 20. comment changer la valeur alpha de l'imageview
- 21. Changer la fonction Valeur de Android Code
- 22. Comment changer la valeur de document.createElement?
- 23. changer la valeur d'attribut de style
- 24. Codeigniter changer la valeur de session cliquez
- 25. comment changer la clé de JSON: Valeur
- 26. knockout dépend de changer la valeur
- 27. changer la valeur de onclick avec jquery
- 28. comment changer la valeur sélectionnée de combobox?
- 29. Comment changer l'heure locale sans utiliser la date
- 30. La pile .NET vs pile de Windows
Cherchez-vous le moyen de le faire dans le code managé ou non géré? –
@Seva: Comme la question est étiquetée SOS, il s'agit probablement d'un code géré. –
@Seva: @Brain est correct, son code managé –