簡體   English   中英

我們如何輕松找到代碼中的哪一行導致運行時異常?

[英]How can we easily find what line in the code causes a runtime exception?

考慮以下分析器:

public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
{
    var throwStatement = node as ThrowStatementSyntax;

    var isObjectCreationExpression = throwStatement.Expression is ObjectCreationExpressionSyntax;
    var obj = throwStatement.Expression as ObjectCreationExpressionSyntax;

    var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;
}

使用SyntaxKind.ThrowStatement作為興趣點。

如果拋出的異常沒有在new Exception()聲明,那么obj應該為null ,而是表示為throw e ,其中e是先前聲明的異常。

當在之后調用obj.Type時,這反過來將拋出NullReferenceException

有問題的例子:

static void Method1()
{
    throw new ArgumentException();
}

static void Method2(ArgumentException e)
{
    throw e;
}

第一次throw會很好地通過分析器,但第二次throw會導致objnull因為它不是ObjectCreationExpressionSyntax類型。

在沙箱Visual Studio環境中,這將顯示為信息消息:

用戶診斷分析器'FormattingFixes.EmptyArgumentException.ArgumentExceptionAnalyzer'拋出異常,並顯示消息'對象引用未設置為對象的實例。'。

在這個簡短的樣本中,很容易分辨問題所在,但在一個不那么人為的例子中,它將更難發現。 行和列都是1 ,沒有幫助。

在“傳統”編程中,您的環境會自動顯示拋出運行時異常的位置以及該時間點的值。 我可以在我的代碼中的某個地方放置一個隨機斷點,每次命中時查看所有值,並嘗試從那里推斷出它,但是一旦節點數遠遠高於這些值,這就不能很好地擴展。

我們如何輕松找到代碼中的哪一行導致運行時異常?

所以你應該還是休息一下,但如果你沒有要檢查的東西:

轉到“調試”菜單下,然后選擇“例外”。 您將看到“Thrown”或“User-unhandled”列。 使用Find查找NullReferenceException,並選中“thrown”復選框。 一旦拋出NullReferenceException,這將導致VS中斷。 如果你想要非常積極,你可以告訴它打破所有例外。

如果仍然無效,請轉到工具>選項,調試,常規並清除“僅我的代碼”。 這里需要注意的是,這會破壞所有例外情況,包括VS部分甚至不是你的錯。 (可悲的是,我們在很多不同的地方都拋出了很多例外。)

如果您願意,請隨意提交錯誤,以便我們可以將消息包括堆棧跟蹤和行/列,以便更容易調試。

因為我在這里:你的代碼確實如此

var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;

注意語法檢查 - 如果我寫了throw new System.ArgumentException()會發生什么? 正確的方法是獲取語義模型並綁定ObjectCreationExpression以確定實際類型是什么。 (如果你在意的話,這也意味着你在別名的情況下工作。)

使用以下步驟獲取引發異常的行號。

  1. 獲取StackTrace以獲取異常。
  2. 獲取堆棧的頂部框架。
  3. 從堆棧框架中獲取行號。

以下是代碼段。

try
{

    //TODO
    throw new Exception();
}
catch (Exception ex)
{
    var stacktrace = new StackTrace(ex, true);
    var frame = st.GetFrame(0);
    var filelinenumber = frame.GetFileLineNumber();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM