2013-03-23 35 views
7

Trước tiên, tôi đã đọc Making a CLR/.NET Language Debuggable, nhưng vẫn gặp sự cố khi triển khai tính năng này.DLR - Tại sao không gỡ lỗi thông tin hiển thị trong ngăn xếp của tôi?

Tôi đã viết một ngôn ngữ đồ chơi hoạt động bằng cách tạo Biểu thức LINQ, sau đó gọi LambdaExpression # CompileToMethod. Hầu hết các biểu thức đã thông tin gỡ lỗi kèm theo như sau:

//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); 
} 

Một DebugInfo trông như thế này:

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

Toàn bộ điều là comipled như vậy (bạn có thể bỏ qua những phần về trong tệp):

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

Mã chạy cung cấp ngoại lệ mà tôi muốn, nhưng không bao gồm thông tin gỡ lỗi mà biểu thức có. Tôi muốn nói điều gì đó như "< 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... 

Dự đoán tốt nhất của tôi là thông tin gỡ lỗi thực sự ở đó, nhưng tôi sẽ phải làm nhiều việc hơn để có được stacktrace hiển thị nó. Bất kỳ ý tưởng?

+0

Chắc chắn công việc hơn, không có gì đơn giản. http://dlr.codeplex.com/discussions/80850 –

+0

"IronRuby duy trì một ánh xạ của IL bù đắp cho số dòng bằng cách cung cấp một DebugInfoGenerator khi biên dịch." Đây là chính xác những gì tôi muốn làm, và mọi biểu thức đã được gắn thẻ với một DebugInfoExpression. Nếu có một cách để đi từ một vị trí IL đến số dòng DebugInfoExpression gần nhất, sau đó tôi có thể tạo một stacktrace. – user1727289

Trả lời

0

Ngoại lệ của bạn là ngoại lệ lồng nhau. Để in ra dấu vết ngăn xếp, hãy xem InnerException.

catch (Exception ex) 
{ 
    while (ex != null) { 
     Debug.Print(ex.ToString()); 
     ex = ex.InnerException(); 
    } 
} 
Các vấn đề liên quan