2016-08-11 56 views
2

我正在使用MDBG示例進行託管.NET調試器。調試器StepInto自動生成的代碼和JMC問題

目前我正在用StepInto行爲掙扎,而StepOut和StepOver似乎正常工作。

要實現Just-My-Code步進,我打電話給模塊加載SetJMCStatus。這工作正常,並允許我只調試我的代碼。

但是,由於我將整個模塊設置爲JMC,一些自動生成的代碼進入遊戲並破壞進入。這種代碼的一個例子可以是自動屬性。

因爲調試器正在執行II指令,所以我介入自動生成的get_propertyNameset_propertyName方法,它們被標記爲我的代碼,因爲它們是我模塊的一部分。

爲了區分這種自動生成的代碼和我的代碼,我可以使用調試符號的存在,在自動生成代碼的情況下缺少。然後我可以簡單地將方法標記爲不是我的代碼,以便在步進時跳過它。

問題是我不知道哪些方法是在步進過程中進入內部之前自動生成的。當我走進一個沒有調試符號的方法時,我可以將它標記爲不是我的代碼,但已經太晚了 - 調試器停在它不應該停止的地方。

理論上我可以使用IMetadataImport在我的模塊方法迭代,並設置其JMCStatus調試器啓動時,但它似乎相當昂貴:

foreach (var methodToken in mdbgModule.Importer.EnumerateAllMethodTokens()) { 
       var func = mdbgModule.GetFunction(methodToken); 
        if (func.SymMethod == null) 
         func.CorFunction.JMCStatus = false; 
      } 

如果只有我會知道是怎麼回事下一個要執行什麼功能,然後我將能夠設置它的狀態,並防止第一次進入自動生成的代碼。

我堅持使用MDBG方法進行步進,不需要改變任何東西,只需在需要的地方調用SetJMCStatus,所以我不確定是否有意義提供任何代碼......如果是這樣,我將編輯問題,只需添加評論!

關於主題的任何建議,非常感謝!

問候,

回答

1

邁克失速hinted的一個選項,你可以爲整個模塊設置JMC,然後在調試器步進休息,檢查,看看是否該方法可調試,如果不是那麼禁用它的JMC狀態和重新運行步進器。 (我不確定這是否會導致行爲發生變化,如果恢復步進器需要在再次踏入之前走出)。

您可以通過僅爲具有pdb可用模塊的JMC設置JMC並通過應用[DebuggerNonUserCode]禁用JMC for classes/methods(也可能爲[DebuggerHidden])。但不是枚舉所有的類/方法並檢查它們是否具有該屬性,而是枚舉自定義屬性並返回(使用tkType設置但不包含tk的IMetaDataImport::EnumCustomAttributes,然後使用IMetaDataImport::GetCustomAttributeProps獲取應用到的東西)。

如果應用於方法級別,您可能可以使用類似於[CompilerGenerated]的屬性,但在類級別應用時會得到誤報(編譯器將它應用於狀態機以獲得迭代器和異步方法,但兩者都可能有非生成的代碼)。

+0

謝謝Brian!我幾次讀過邁克斯托爾的那篇文章,但即使現在我也無法從中得到提示!無論如何,重新運行步進似乎是一個沉悶的想法!我會馬上嘗試,並讓你知道。 CompilerGenerated屬性的問題是屬性get/set有時可能包含用戶代碼。 – 3615

+0

順便說一句,我已經更新了與我的最初想法相關的一些代碼的問題 - 迭代方法。我從IMetadataTables.GetTableInfo獲取methodDefs的數量,然後創建在ICorDebugModule.GetFunctionFromToken中使用的順序標記。 – 3615

+0

我提到的提示是在倒數第二段的最後一句中。 「這也讓調試器延遲設置JMC狀態,直到用戶第一次停止該方法。」 –