2016-09-13 21 views
5

Tôi đang tạo một trình gỡ lỗi .NET được quản lý bằng mẫu MDBG. Nó hoạt động cho các tình huống đơn giản, nhưng có vấn đề khi viết lại phương thức xảy ra. Hầu hết các bộ phận quan trọng là phương pháp lợi nhuận và phương pháp không đồng bộ.Công cụ gỡ lỗi. Phương pháp viết lại, biến cục bộ và biến phân giải

Tôi đã hỏi tổng quát hơn question về các sự cố này. Bây giờ tôi muốn tập trung vào độ phân giải biến cục bộ. Hãy xem xét các mã:

using System; 
    using System.Threading.Tasks; 

    class C 
    { 
     public static void Main() { 

      var instance = new Instance(); 
      instance.Start().Wait(); 
     } 
    } 
    class Instance 
    { 
     public static async Task F() { for(var i=0; i<100; i++) { Console.WriteLine(i); await Task.Delay(100); } } 
     public async Task Start() { 
      var z = "test";<------- Breakpoint 
      var x = 10; 
      await F(); 
     } 
    } 

Khi debugger đạt Breakpoint tôi truy vấn gỡ rối để có được các biến cục bộ và biến duy nhất là this. Các biến số xz được lưu trữ trên cấu trúc được tạo và không thể được giải quyết trực tiếp Image.

Câu hỏi đặt ra là: Cách giải quyết trong khi gỡ lỗi biến cục bộ trong phương thức lợi nhuận và phương pháp không đồng bộ?

Trong nhận xét cho câu hỏi trước đây của tôi @Brian Reichle đã cho tôi một số gợi ý làm cách nào tôi có thể lấy ánh xạ giữa biến hiện tại và được đặt trong danh sách. Khám phá SymAttribute và nguồn Roslyn Tôi đi đến kết luận rằng nó không trực tiếp lưu trữ ánh xạ giữa chúng. SymAttribute được sử dụng để có được CustomDebugInfoRecord, mà các cửa hàng một phần của thông tin này (sử dụng thư viện Pdb2Xml từ Roslyn để tạo ra nó):

<method containingType="Instance+&lt;Start&gt;d__1" name="MoveNext"> 
     <customDebugInfo> 
     <forward declaringType="C" methodName="Main" /> 
     <hoistedLocalScopes> 
      <slot startOffset="0x0" endOffset="0xcc" /> 
      <slot startOffset="0x0" endOffset="0xcc" /> 
     </hoistedLocalScopes> 
     <encLocalSlotMap> 
      <slot kind="27" offset="0" /> 
      <slot kind="33" offset="161" /> 
      <slot kind="temp" /> 
      <slot kind="temp" /> 
     </encLocalSlotMap> 
     </customDebugInfo> 
     <sequencePoints> 
     <entry offset="0x0" hidden="true" document="1" /> 
     <entry offset="0x7" hidden="true" document="1" /> 
     <entry offset="0xe" startLine="16" startColumn="37" endLine="16" endColumn="38" document="1" /> 
     <entry offset="0xf" startLine="17" startColumn="14" endLine="17" endColumn="29" document="1" /> 
     <entry offset="0x1a" startLine="18" startColumn="14" endLine="18" endColumn="35" document="1" /> 
     <entry offset="0x26" startLine="19" startColumn="14" endLine="19" endColumn="25" document="1" /> 
     <entry offset="0x2e" startLine="19" startColumn="25" endLine="19" endColumn="46" document="1" /> 
     <entry offset="0x3a" startLine="20" startColumn="14" endLine="20" endColumn="24" document="1" /> 
     <entry offset="0x45" hidden="true" document="1" /> 
     <entry offset="0xa0" hidden="true" document="1" /> 
     <entry offset="0xb8" startLine="21" startColumn="11" endLine="21" endColumn="12" document="1" /> 
     <entry offset="0xc0" hidden="true" document="1" /> 
     </sequencePoints> 
     <asyncInfo> 
     <kickoffMethod declaringType="Instance" methodName="Start" /> 
     <await yield="0x57" resume="0x72" declaringType="Instance+&lt;Start&gt;d__1" methodName="MoveNext" /> 
     </asyncInfo> 
    </method> 

Vì vậy, cách duy nhất tôi có thể nhìn thấy bây giờ để giải quyết biến kéo lên là:

  1. Kiểm tra xem phương pháp có được viết lại hay không.
  2. Đối với phương thức như vậy, hãy truy cập asyncInfo và thấy nó đang chờ khai báoType. Nó cung cấp cho tên của cấu trúc được tạo ra và nơi các biến được hoisted.
  3. Resolve this.generatedStructureName
  4. Roslyn mã nguồn tiết lộ naming conventions for hoisted variables, có thể được sử dụng để dịch x biến thành <x>5__2

Cách tiếp cận này không có vẻ đúng và tôi không chắc chắn nếu nó bao giờ sẽ làm việc ra, nhưng đó là điều duy nhất tôi có thể nghĩ đến bây giờ. Có khả năng nào khác để giải quyết vấn đề này không? Làm thế nào để VisualStudio giải quyết nó?

Tôi đã tạo một repo nhỏ để tạo lại vấn đề here

Trả lời

1

Vâng, tôi đã không tìm thấy bất cứ ai ở đây hoặc trên các diễn đàn MSDN người sẽ soi sáng cho tôi về cách VS công trình thuật toán, nhưng tôi đã phát hiện ra rằng SharpDevelop hỗ trợ độ phân giải biến cho các phương thức không đồng bộ. Đáng ngạc nhiên là nó đã được sử dụng thuật toán tương tự như những gì tôi đã mô tả trong câu hỏi của tôi: chỉ cần phân tích cú pháp tên trường hoisted.

Nguồn liên quan có thể có sẵn here trên gitHub, nếu người khác sẽ gặp phải sự cố tương tự và sẽ bị kẹt. Tuy nhiên, tôi không coi đây là một giải pháp tốt và hy vọng có một cách tốt hơn để giải quyết vấn đề này ...

Các vấn đề liên quan