2016-08-31 21 views
1

我們正在開發一個靜態代碼分析工具,旨在通過一些提示改進代碼。如何在靜態代碼分析工具中找到NullReferenceException的潛在點?

我們希望找到開發人員忘記檢查變量或屬性或方法返回的可空性並通過點符號訪問成員的地方,因爲它可能遇到NullReferenceException。

例如下面的代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var human = new Human(); 
     if (human.Name.Length > 10) 
     { 
      // Jeez! you have a long name; 
     } 
    } 
} 

public class Human 
{ 
    public string Name { get; set; } 
} 

我們使用Mono.Cecil能做到,我們發現在一個特定的裝配所有類型的所有方法的身體,併爲每個方法體,我們發現它的說明,並然後我們檢查Callvirt操作。然而,這並不支持這個例子:

class Program 
{ 
    static string name; 

    static void Main(string[] args) 
    { 
     if (name.Length > 10) 
     { 
     } 
    } 
} 

我們如何才能找到所有的訪問給定可空類型的成員(變量,字段,屬性,方法)?

更新: 事實上,我們正在尋找代表在IL給定的變量成員訪問操作碼。這可能嗎?

+0

你想創建一個工具,它使用反射進行靜態代碼分析*,這是一個不小的技巧*,但是有關於如何使用反射的基本問題?我認爲你是在這匹馬前面放馬。我建議你先學習所有關於反射的知識。然後,您需要了解如何破壞方法,以便您的代碼可以找到像上面這樣的情況(這是更難的部分)。哦,是的,之後你將不得不通知用戶(不知道這是內聯還是通過控制檯輸出)。順便說一下,那裏有很多工具可以完成這些工作。 – Igor

+0

像https://www.jetbrains.com/resharper這樣的工具會讓你知道(內聯)是否存在NullReferenceException的可能性等等。 –

+0

@Igor我們已經使用*簽入策略*開發了基於* TFS *的代碼分析/質量。目前,它檢查了我們定義的超過180條規則,以提高大約15位開發人員開發的多個龐大代碼庫的質量。 這個問題是關於一個我們想要添加的新規則 - 每當需要時應該在那裏檢查,以防止NullReferenceException。 –

回答

2

NullReferenceException的文檔很有幫助介紹以下:

下面的Microsoft中間語言(MSIL)指令 拋NullReferenceExceptioncallvirtcpblkcpobjinitblkldelem.<type>ldelemaldfldldfldaldind.<type>,ldlenstelem.<type>,stfld,, throwunbox

這些分解爲以下幾點:

  • 數組訪問:ldelemldelemaldlenstelem。數組引用不得爲null
  • 非陣列成員訪問:ldfld,ldflda,stfld。對象引用不得爲null
  • 方法訪問:callvirt。對象引用不得爲null。屬性訪問也是方法訪問​​,因爲它調用屬性getter/setter。
  • 指針/參考訪問:cpblk,cpobj,initblk,ldind,stind。指針/參考不能是null。在經過驗證的託管代碼中,這些操作碼通常不會在其參數可能爲null的上下文中使用。
  • 拋出異常:throw。異常參考不得爲null
  • 拆箱:unbox。對象引用不得爲null

將操作碼參數追溯回變量/字段是另一個問題。這可能是任意複雜的,因爲操作碼只關心棧上的內容,而不關心棧的內容。在某些情況下,您可能正在處理表達式(a[0].SomeMethod().FieldAccess,其中a,a[0]a[0].SomeMethod()中的任何一個可能是null)。

你最好不要在IL級別上檢查它,而是使用Roslyn爲您提供語言級別的分析。通過訪問源代碼來生成高質量的反饋非常簡單。

即使如此,請注意,高質量的靜態分析並不容易。你當然可以編寫一個分析器,它會在程序員可能忘記檢查的每一種可能情況下高興地發出警告,但是如果程序員被迫爲顯式引用插入大量多餘的檢查,那麼這樣的分析器幾乎變得毫無用處從不null。如果您將此與TFS簽入政策聯繫起來,請準備好接受開發人員和管理人員的死亡威脅,他們想知道爲什麼生產力急劇下降。

有一個原因,像Resharper現有的工具添加了很多attributes控制分析,並有一個proposal最多添加到C#本身的可空性檢查。在重新開始之前知道你正在進入什麼。