7
首先,我讀過Making a CLR/.NET Language Debuggable,但我仍然無法執行此操作。DLR - 爲什麼調試信息不會顯示在我的堆棧跟蹤中?
我寫了一個玩具語言,它通過生成一個Linq表達式,然後調用LambdaExpression#CompileToMethod。大多數這些表述都附加調試信息,像這樣:
//SmithExpression#InsertDebugInfo
Expression InsertDebugInfo(Expression expression, DebugInfo debugInfo) {
var column = 1;
var debugExpr = Expression.DebugInfo(debugInfo.SymbolDocumentInfo
,Info.LineNumber, column, Info.LineNumber, column + 1);
return Expression.Block(debugExpr, expression);
}
一個debuginfo軟看起來是這樣的:
public class DebugInfo {
/* arbitrary value from http://www.famkruithof.net/uuid/uuidgen */
public static Guid SmithGuid = new Guid("83c65910-8376-11e2-9e96-0800200c9a66");
public readonly SymbolDocumentInfo SymbolDocumentInfo;
public readonly DebugInfoGenerator DebugPdbGenerator;
public DebugInfo(String name) {
SymbolDocumentInfo = Expression.SymbolDocument(name, SmithGuid);
DebugPdbGenerator = DebugInfoGenerator.CreatePdbGenerator();
}
}
整件事是comipled像這樣(你可以忽略關於inits的部分):
public static Action CompileSmithExpression(SmithExpression sexpression
,DebugInfo debugInfo, Parameter moduleParameter, Expando module) {
AssemblyName assemblyName =
new AssemblyName(
"RuntimeHelpers.CompileToSmithExpression helper assembly"
);
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.RunAndSave
);
ModuleBuilder moduleBuilder = assemblyBuilder
.DefineDynamicModule(assemblyName.Name, "onlyModule.dll");
var debugAttributes =
DebuggableAttribute.DebuggingModes.Default |
DebuggableAttribute.DebuggingModes.DisableOptimizations;
ConstructorInfo constructor =
typeof(DebuggableAttribute)
.GetConstructor(new Type[] {
typeof(DebuggableAttribute.DebuggingModes)
}
);
var cab = new CustomAttributeBuilder(constructor, new object[] { debugAttributes });
assemblyBuilder.SetCustomAttribute(cab);
moduleBuilder.SetCustomAttribute(cab);
TypeBuilder typeBuilder =
moduleBuilder.DefineType("MyDynamicType", TypeAttributes.Public);
//inits generates expressions that set 'constant' fields to their values.
//the call also adds the 'constant' fields to the typeBuilder.
//Must call ToArray() to make it run.
var inits = FieldInits(sexpression, typeBuilder).ToArray();
var ex = sexpression.ToExpression(debugInfo);
var fullDlrExpression = Expression.Block(inits.Append(ex));
var parameters = new ParameterExpression[] { moduleParameter.DlrParameter };
var lambda = Expression.Lambda(fullDlrExpression, parameters);
/* Method will take the module as a parameter. */
MethodBuilder meth = typeBuilder.DefineMethod(
"MyMethod",
MethodAttributes.Public | MethodAttributes.Static,
typeof(void),
new Type[] { typeof(Expando) });
lambda.CompileToMethod(meth, debugInfo.DebugPdbGenerator);
Type madeType = typeBuilder.CreateType();
return() => madeType.GetMethod("MyMethod").Invoke(null, new Object[] { module });
}
運行代碼給出我想要的異常,但不包括表達式的調試信息。我希望它能說「< error_immediate,1 >」。
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.MissingMemberException: Can't invoke member error of [] []
at (wrapper dynamic-method) object.CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,Smith.Expando) <IL 0x0004f, 0x00127>
at System.Dynamic.UpdateDelegates.UpdateAndExecute1<Smith.Expando, object> (System.Runtime.CompilerServices.CallSite,Smith.Expando) <0x0040b>
at MyDynamicType.MyMethod (Smith.Expando) <IL 0x002bc, 0x00aaa>
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) <IL 0x00016, 0x00067>
etc...
我最好的猜測是,調試信息實際上是存在的,但我必須做更多的工作來獲得堆棧跟蹤顯示它。有任何想法嗎?
絕對有更多的工作,沒有什麼簡單的。 http://dlr.codeplex.com/discussions/80850 – 2013-03-24 01:30:04
「編譯時,IronRuby通過提供DebugInfoGenerator來維護IL偏移到行號的映射。」這正是我想要做的,每個表達式都已經用DebugInfoExpression標記。如果有從IL位置到最接近它的DebugInfoExpression行號的方法,那麼我可以進行堆棧跟蹤。 – user1727289 2013-03-24 01:54:59