簡體   English   中英

啟用優化后,DotNet錯誤的代碼步進

[英]DotNet Incorrect code stepping when optimisations enabled

我遇到的一種情況是,當打開優化功能(即在發布模式下)時,c#編譯器正在做一些奇怪的事情,並且您開始逐步執​​行代碼(關閉“僅啟用我的代碼”)

我有與以下代碼類似的代碼,它的工作基本上是看設置提供程序是否具有要設置的應用程序環境,否則將單獨處理該環境。

var environmentValue = settingsProvider.ApplicationEnvironment;
if (!string.IsNullOrWhiteSpace(environmentValue))
{
    switch (environmentValue.ToLower())
    {
        case "p":
            _connectionSettings.Production();
            break;
        case "t":
            _connectionSettings.Test();
            break;
        case "d":
            _connectionSettings.Development();
            break;
        case "l":
            _connectionSettings.Local();
            break;
    }
}

但是,當啟用優化時,即使environmentValue的值為null,也總是會打最后一個case語句,即,不應首先進入開關。

我不得不更改代碼,以使它像這樣,現在變為默認值:case。

var environmentValue = settingsProvider.ApplicationEnvironment;
if (!string.IsNullOrWhiteSpace(environmentValue))
{
    switch (environmentValue.ToLower())
    {
        case "p":
            _connectionSettings.Production();
            break;
        case "t":
            _connectionSettings.Test();
            break;
        case "d":
            _connectionSettings.Development();
            break;
        case "l":
            _connectionSettings.Local();
            break;
        default:
            Console.WriteLine(environmentValue);
            break;
    }
}

我正在通過Visual Studio 2015,框架版本4.5.1,發行模式,任何CPU(首選32位)和“啟用我的代碼”功能關閉此程序。

當我第一次開始這篇文章時,我沒有意識到那只是在單步執行代碼時。 但是,由於我沒有一步步執行代碼,而仍然遇到最后一個case語句,所以它似乎確實有一些奇怪的行為。

我還創建了一個說明問題的要點項目。

https://gist.github.com/matthewvukomanovic/899d595cd0b787116b95ddb5f2b128d3#file-program-cs

在我編寫的測試應用程序中,此后只需要執行另一個調用即可強制其正確運行,但是在實際應用程序中,它已經具有使用同一對象的其他調用,但是它的工作原理並不相同。

除了添加像我一樣的虛擬默認案例之外,沒有人知道在逐步優化代碼時如何避免此問題?

通常,發布版本的代碼是一個問題, 優化器會對代碼進行重新排序,並使從可執行的機器代碼到程序中源代碼的映射變得模糊。 這是首先存在Debug配置的基本原因。 單步執行和斷點操作不是唯一的錯誤調試功能,檢查局部變量也將停止工作。

有一個調試器選項,即使您使用Release構建的代碼,也可以在使用調試器時強制禁用優化器。 使用工具>選項>調試>常規>選中“禁止JIT優化”復選框。 默認情況下啟用。 打開該選項,您的示例程序將正常運行。 因此,您可能已將其關閉。

該選項不能總是有效,將調試器連接到正在運行的程序或使用Debugger.Break()插入時將無法使用。 請記住,修改代碼是不必要的。 您可以從您的repro片段中得知它實際上並未調用Local()方法。 它只是突出顯示了錯誤的源代碼行,僅此而已。 模糊映射。 請記住,當您調試代碼的Release版本時,調試將變得很困難,您將處於領先地位。 並重新打開該選項。

暫無
暫無

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

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