.net Emit 動態創建類型之源代碼級調試

長達N年的XXXXX工作終於結束,今天終於迴歸技術,特寫此篇博文,開個好頭
度娘竟然沒有搜出一篇關於Emit動態創建類型調試相關的內容?
難道要用windbg?!!!!DbgClr在VS2010中也消失不見,瘋了
果斷問google,找到了一篇英文emit調試說明
原文見:http://blogs.msdn.com/b/jmstall/archive/2005/02/03/366429.aspx
爲照顧英文小白和象我一樣的半桶水,特寫一篇中文emit調試方法:
1.引入以下命名空間:

using System.Diagnostics;
using System.Diagnostics.SymbolStore;
2.程序集按以下定義:

AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("xxxx"), AssemblyBuilderAccess.RunAndSave);
看到沒,要RunAndSave,至少要Run


3.給動態程序集加入DebuggableAttribute特性:

//定義調試信息
CustomAttributeBuilder debugAttributeBuilder=new CustomAttributeBuilder(
typeof(DebuggableAttribute).GetConstructor(new Type[]{typeof(DebuggableAttribute.DebuggingModes)}),
new object[] {
DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.Default
}
);
assemblyBuilder.SetCustomAttribute(debugAttributeBuilder);


4.還要給模塊定義加入:

ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MastzouBase.DynamicProxy.Proxy.dll", "MastzouBase.DynamicProxy.Proxy.dll", true);//關鍵這裏要true
ISymbolDocumentWriter DOC = moduleBuilder.DefineDocument(@"d:\IL的cs源代碼片斷在這裏.txt", Guid.Empty, Guid.Empty, Guid.Empty);//要定義源代碼位置,這個文檔不需要全部源代碼,只需要你想調試的il源代碼翻譯就可以了

5.好了,按照1,2,3,4你的程序集已經做好被調教的準備了,現在開始說具體怎麼調

引用個例子"世界你好:
先寫源代碼d:\IL的cs源代碼片斷在這裏.txt內容如下:
// Test
xyz = "hello";
Write(xyz);
return;
然後把源代碼翻譯成emit如下:
ILGenerator ilGenerator = methodbuilder.GetILGenerator(); //
LocalBuilder localXYZ = ilGenerator.DeclareLocal(typeof(string));
localXYZ.SetLocalSymInfo("xyz"); //看到沒,設置下變量名,有助於調試
// Line 2: xyz = "hello";
ilGenerator.MarkSequencePoint(doc, 2, 0, 2, 100);//設置代碼對應,意思是:下面IL代碼對應的cs源代碼所在的行和列,這裏是第2行第0列開始,到第2行100列結束。注意行是從1開始算起,列是0開始算起。什麼?爲什麼這裏是2不是1,你沒看到" d:\IL的cs源代碼片斷在這裏.txt"文件中第一行是註釋麼!!!!爲什麼是100列結束?你高興可以設置成200!!!
ilGenerator.Emit(OpCodes.Ldstr, "世界你好!");
ilGenerator.Emit(OpCodes.Stloc, localXYZ); //看到沒?這就是設置變量名的好處,異讀!!
// Line 3: Write(xyz);第二行對應結束了,這裏是第3行的il代碼
MethodInfo infoWriteLine = typeof(System.Console).GetMethod("WriteLine", newType[] { typeof(string) }); ilGenerator.MarkSequencePoint(doc, 3, 0, 3, 100);//設置代碼對應,這不用再解釋了吧!
ilGenerator.Emit(OpCodes.Ldloc, localXYZ);
ilGenerator.EmitCall(OpCodes.Call, infoWriteLine, null);
// Line 4: return;
ilGenerator.MarkSequencePoint(doc, 4, 0, 4, 100);//這不用再解釋了吧!
ilGenerator.Emit(OpCodes.Ret);
好了代碼對應也好了,現在方法也做好了被調教得準備了,所有調試準備都做完了
6。emit動態il源代碼級調試!!!
用vs2010或者啥啥啥版本在工程打開d:\IL的cs源代碼片斷在這裏.txt(不用把文件加入工程,當然如果你想,那也是可以的,好處是便於下次調試
打開後,你可以在其中隨便設置斷點,然後開調吧(注意不要破壞代碼對應哦)
7。這個方法
不能調試emit發出的動態方法
,那咋調?等待我下個帖子吧,騷年!!

小提示:ildasm.exe加Reflector.exe你懂得,嘿嘿
全文結束,祝你好運,再見




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章