2013-03-23 14 views
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); 
} 

A 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(); 
    } 
} 

全部が(あなたがのINITに関する部分を無視することができる)ので、同じようcomipledさ:

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... 

私の最高の推測では、デバッグ情報が実際に存在しているが、私はそれを表示するスタックトレースを取得するために多くの作業を行う必要があるでしょうということです。何か案は?

+0

明らかに多くの仕事、単純なものはありません。 http://dlr.codeplex.com/discussions/80850 –

+0

"IronRubyはコンパイル時にDebugInfoGeneratorを提供することにより、IL番号のオフセットをライン番号にマッピングします。"これはまさに私がやりたいことであり、すべての式は既にDebugInfoExpressionでタグ付けされています。 ILの場所から最も近いDebugInfoExpression行番号に行く方法があれば、私はスタックトレースを作ることができます。 – user1727289

答えて

0

例外はネストされた例外です。スタックトレースを出力するには、InnerExceptionを見てください。

catch (Exception ex) 
{ 
    while (ex != null) { 
     Debug.Print(ex.ToString()); 
     ex = ex.InnerException(); 
    } 
} 
関連する問題