.NET, Architecture, ALM, Cloud

Publicité

Récupérer le code IL de vos méthodes dynamiques

Petit tutorial très pratique qui va nous permettre de récupérer le Code IL de nos méthodes dynamiques et donc de nos expressions lambda compilé à la volée.

 

Prenons un exemple simple :

Expression<Func<int, int>> methodE = a => a * 2;
var
method = methodE.Compile();
int
result = method(4);

 

On va donc récupérer le code IL généré du corps de notre méthode "a * 2" qui a donc un paramètre a de type Integer et qui retourne un Integer.

Avant de voire en détail comment procéder, comment nous allons nous y prendre ? : A l'aide de l'extension de débogage SOS de Microsoft, nous allons récupérer l'adresse de notre Func puis de notre méthode dynamique pour ensuite récupérer le code IL de celle-ci.

 

Tout d'abord, activer le debug du code non managé dans votre projet (Fenêtre VS de Propriété de votre projet, onglet "Debug" puis cochez "Enable unmanaged code debugging"). Lancez votre application en positionnant un point d'arrêt une fois que votre expression a été compilé, puis à partir de la fenêtre de Debug Visual Studio "Immediate Window", lancez les commande suivante (et servez vous des résultats de chaque commande pour adapter la suivante) :

.load sos

!dso
PDB symbol for clr.dll not loaded
OS Thread Id: 0x1730 (5936)
ESP/REG  Object   Name
...
002EF00C 02562b94 System.Func`2[[System.Int32, mscorlib],[System.Int32, mscorlib]]
...



!do 02562b94
Name:        System.Func`2[[System.Int32, mscorlib],[System.Int32, mscorlib]]
MethodTable: 00182820
EEClass:     0018004c
Size:        32(0x20) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
6b6ef5e8  4000074        4        System.Object  0 instance 02562afc _target
6b6ef5e8  4000075        8        System.Object  0 instance 0255e4a4 _methodBase
6b6eaa2c  4000076        c        System.IntPtr  1 instance 003C00B0 _methodPtr
6b6eaa2c  4000077       10        System.IntPtr  1 instance 00000000 _methodPtrAux
6b6ef5e8  4000078       14        System.Object  0 instance bf8c6aa000000000 _invocationList
6b6eaa2c  4000079       18        System.IntPtr  1 instance 00000000 _invocationCount

!do 0255e4a4
Name:        System.Reflection.Emit.DynamicMethod+RTDynamicMethod
MethodTable: 6b6af24c
EEClass:     6b3fc920
Size:        28(0x1c) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
6b6f1938  4002932        4 ...mit.DynamicMethod  0 instance 0255d188 m_owner
6b6a6c28  4002933        8      System.Object[]  0 instance bfb0786800000000 m_parameters
6b6ef9ac  4002934        c        System.String  0 instance 0255d024 m_name
6b6ab7bc  4002935       10         System.Int32  1 instance       22 m_attributes
6b6ab608  4002936       14         System.Int32  1 instance        1 m_callingConvention

!dumpil 0255d188
This is dynamic IL. Exception info is not reported at this time.
If a token is unresolved, run "!do <addr>" on the addr given
in parenthesis. You can also look at the token table yourself, by
running "!DumpArray 0255e890".

IL_0000: ldarg.1
IL_0001: ldc.i4.2
IL_0002: mul
IL_0003: ret

 

Nous chargeons SOS via la commande ".load sos", ensuite nous récupérons l'adresse de nos objets via "!dso" (dso pour dumpstackobjects). On récupère  l'adresse de notre Func pour ensuite récupérer l'adresse de sa méthode via la commande "do" (pour dumpobject) en précisant son adresse, et en récupère enfin l'adresse de notre méthode dynamique toujours à l'aide de "do".

 

Il nous suffit alors d'utiliser la commande "dumpil" en précisant l'adresse de la méthode pour récupérer son code IL.

Publicité
Retour à l'accueil
Partager cet article
Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article