.net – DLR – 为什么我的堆栈跟踪中没有显示调试信息?

首先,我已经阅读了 Making a CLR/.NET Language Debuggable,但我仍然无法实现这一点.

我编写了一种玩具语言,通过生成Linq表达式,然后调用LambdaExpression#CompiletoMethod.大多数这些表达式都附带调试信息,如下所示:

//SmithExpression#InsertDebugInfo
Expression InsertDebugInfo(Expression expression,DebugInfo debugInfo) {
    var column = 1;
    var debugExpr = Expression.DebugInfo(debugInfo.SymbolDocumentInfo,Info.LineNumber,column,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();
    }
}

整个事情都是这样的(你可以忽略关于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...

我最好的猜测是调试信息确实在那里,但是我必须做更多的工作来让stacktrace显示它.有任何想法吗?

解决方法

您的异常是嵌套异常.要打印出堆栈跟踪,请查看InnerException.
catch (Exception ex)
{
    while (ex != null) {
        Debug.Print(ex.ToString());
        ex = ex.InnerException();
    }
}

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...