簡體   English   中英

Visual Studio 2010調試器中的上下文變量

[英]Out Of Context Variables In Visual Studio 2010 Debugger

對於面向.NET 4.0的C#控制台應用程序,Visual Studio 2010調試器中的局部變量脫離上下文,我遇到了一個非常奇怪的問題。 我在SO上搜索過其他類似的問題,但有些問題有相同的症狀,似乎沒有一個直接適用於這個問題(它們似乎都有其他根本原因)。

問題是,對於某些變量(但不是全部),我沒有得到帶有它們值的工具提示,它們沒有出現在Locals窗口中,並且我得到“當前上下文中不存在名稱'xyz'”如果我將它們添加到Watch窗口。 它似乎影響了一些變量而不影響其他變量,我無法弄清楚一個模式(它似乎不是基於成員與本地,類與結構或任何其他區別)。 我已經重新啟動了我的計算機和Visual Studio,驗證了我是一個干凈的Debug版本,確保調試框架是正確的,確保刷新監視屏幕中的變量,並嘗試各種法術和咒語。

我在下面添加了一個屏幕截圖( http://i.stack.imgur.com/JTFBT.png上的更大版本)。

在此輸入圖像描述

有什么想法嗎?

編輯:

添加一些其他信息:

問題是可重復的。 即使在完全關閉並重新啟動Visual Studio之后,完全相同的變量也可以工作或不起作用。 這讓我相信實際上存在系統性錯誤,而不僅僅是內存損壞或其他問題。

我還發現它似乎與try-catch塊有關。 如果我將斷點放在try語句之外,我可以正常看到任何范圍內的變量。 一旦執行點進入try語句,try塊之外的所有變量都將變得不可訪問,我只能訪問try語句中的變量。 這幾乎就像調試器將try塊視為一個單獨的方法一樣(盡管你可以看到代碼/編譯器仍然可以訪問范圍內的變量)。 以前有人見過這種行為嗎?

另一個編輯:

我(部分)收回了我所說的關於try-catch被懷疑的內容 - 似乎在代碼的這一部分中,調試器展示了這個奇怪的東西在任何封閉塊的上下文之外。 例如,如果我在屏幕截圖中的foreach語句中直接設置斷點,我可以在每次迭代時看到“port”變量值,但是在foreach語句之外沒有變量(一旦我進入foreach塊就會消失) 。 然后,只要您進入try塊,“port”變量就會突然消失。 這變得非常奇怪。

此外,根據要求,整個方法的代碼如下。

private void ConfigureAnnouncerSockets(XDocument configDocument)
{
    XElement socketsElement = configDocument.XPathSelectElement("/Configuration/Network/AnnouncerSockets");
    bool useDefault = true;
    if (socketsElement != null)
    {
        //Use the default announcers? (they will be added at the end)
        XAttribute defaultAttribute = socketsElement.Attribute("useDefault");
        if (defaultAttribute != null)
        {
            useDefault = Convert.ToBoolean(defaultAttribute);
        }

        //Get the default frequency
        int defaultFrequency = Announcer.DefaultFrequency;
        XAttribute frequencyAttribute = socketsElement.Attribute("frequency");
        if (frequencyAttribute != null)
        {
            defaultFrequency = Convert.ToInt32(frequencyAttribute.Value);
        }

        //Get all sockets
        foreach (XElement socketElement in socketsElement.XPathSelectElements("./Socket"))
        {
            //Get the address
            IPAddress address = IPAddress.Broadcast;
            string addressAttribute = (string)socketElement.Attribute("address");
            if(!GetAddress(addressAttribute, ref address, true))
            {
                Intelliplex.Log.Warn("Invalid announcer socket address: " + addressAttribute);
                continue;
            }

            //Get the local address
            IPAddress localAddress = null;
            string localAddressAttribute = (string)socketElement.Attribute("localAddress");
            if(!GetAddress(localAddressAttribute, ref localAddress, false))
            {
                Intelliplex.Log.Warn("Invalid announcer socket local address: " + localAddressAttribute);
                continue;
            }

            //Get the port(s)
            List<int> ports = new List<int>();
            string[] ranges = ((string)socketElement.Attribute("port")).Split(new[] { ',' });
            foreach (string range in ranges)
            {
                string[] portPair = range.Split(new[] { '-' });
                int firstPort = Convert.ToInt32(portPair[0]);
                int lastPort = portPair.Length > 1 ? Convert.ToInt32(portPair[1]) : firstPort;
                do
                {
                    ports.Add(firstPort);
                } while (++firstPort <= lastPort);
            }

            //Get the local port
            int localPort = socketElement.Attribute("localPort") != null
                ? Convert.ToInt32((string)socketElement.Attribute("localPort")) : 0;

            //Get the frequency
            int frequency = socketElement.Attribute("frequency") != null
                ? Convert.ToInt32((string)socketElement.Attribute("frequency")) : defaultFrequency;

            //Create the socket(s) and add it/them to the manager
            foreach (int port in ports)
            {
                try
                {
                    IPEndPoint endPoint = new IPEndPoint(address, port);
                    IPEndPoint localEndPoint = localAddress == null
                        ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(localAddress, localPort);
                    Announcer socket = new Announcer(frequency, endPoint, localEndPoint);
                    AnnouncerSockets.Add(socket);
                }
                catch (Exception ex)
                {
                    Intelliplex.Log.Warn("Could not add announcer socket: " + ex.Message);
                }
            }
        }
    }

    //Add default announcement sockets?
    if (useDefault)
    {
        ConfigureDefaultAnnouncerSockets();
    }
}

所以事實證明這與PostSharp中的錯誤有關。 我一直在使用PostSharp,但從我的代碼中刪除了所有方面,並確保沒有應用。 我還用Reflector驗證了方法在裝配中是完整的。 但是,它似乎只是引用PostSharp觸發某種導致此問題的調試符號的操作。 可以在這里找到(小)更多信息:

http://www.sharpcrafters.com/forum/Topic5794-21-1.aspx#bm7927

此外,在最新的PostSharp修補程序的發行說明中,修補程序2.1.5.6中的一個已修復問題是“調試符號:隱式迭代器中丟失的局部變量符號”。

當我安裝最新最好的PostSharp時,問題消失了,宇宙恢復正常。 希望這個問題/答案將幫助其他任何使用PostSharp的人在下一次官方PostSharp發布之前偶然發現這種奇怪的行為。 確保你使用的是修補程序2.1.5.6或更高版本(鑒於錯誤的嚴重性,這可能應該是一個實際版本)。

謝謝各位的幫助。

暫無
暫無

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

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