2011-12-29 14 views
16

Ho un problema molto strano con le variabili locali che sono fuori dal contesto nel debugger di Visual Studio 2010 per un'applicazione console C# che utilizza .NET 4.0. Ho cercato altre domande simili su SO, ma mentre alcuni hanno gli stessi sintomi, nessuno sembra applicarsi direttamente a questo problema (tutti sembrano avere altre cause).Variabili fuori contesto in Visual Studio 2010 Debugger

Il problema è che per alcune variabili (ma non tutte) non ottengo un suggerimento con il loro valore, esse non compaiono nella finestra Locali e ottengo "Il nome 'xyz' non esiste nell'attuale contesto "se li aggiungo alla finestra di controllo. Sembra che influenzi alcune variabili ma non altre, e non riesco a capire un modello (non sembra essere basato su membro vs. locale, classe vs. struct o qualsiasi altro elemento di differenziazione). Ho riavviato il mio computer e Visual Studio, ho verificato che sono in una build debug pulita, mi sono assicurato che il frame di debug fosse corretto, mi sono assicurato di aggiornare le variabili nella schermata di controllo e ho tentato vari incantesimi e incantesimi.

Ho incluso uno screenshoot di seguito (versione più grande a http://i.stack.imgur.com/JTFBT.png).

enter image description here

Qualche idea?

EDIT:

Aggiunta di alcune informazioni aggiuntive:

Il problema è ripetibile. Le stesse variabili esatte funzionano o non funzionano, anche dopo aver completamente chiuso e riavviato Visual Studio. Questo mi porta a credere che ci sia in realtà qualcosa di sistematico che va storto piuttosto che solo la corruzione della memoria o qualcosa del genere.

Ho anche scoperto che sembra essere correlato al blocco try-catch. Se posizioni il punto di interruzione all'esterno dell'istruzione try, è possibile vedere normalmente qualsiasi variabile nell'ambito. Non appena il punto di esecuzione entra nella dichiarazione try tutte le variabili al di fuori del blocco try diventano inaccessibili e posso accedere solo a quelle contenute nell'istruzione try. È quasi come se il debugger trattasse il blocco try come metodo separato (sebbene si possa vedere che il codice/compilatore ha ancora accesso alle variabili in-scope). Qualcuno ha mai visto questo comportamento prima?

ALTRO EDIT:

I (parzialmente) riprendere quello che ho detto circa il try-catch essendo sospetto - sembra che in questa parte del codice mostre debugger questa presa di roba strana fuori contesto per qualsiasi racchiude bloccare. Ad esempio, se imposto un breakpoint direttamente all'interno dell'istruzione foreach nello screenshot, posso vedere il valore della variabile "port" su ogni iterazione, ma nessuna delle variabili al di fuori dell'istruzione foreach (che scompare non appena inserisco il blocco foreach) . Quindi, non appena si inserisce il blocco try, la variabile "port" scompare improvvisamente. Questo sta diventando davvero strano.

Inoltre, come richiesto, il codice per l'intero metodo è riportato di seguito.

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(); 
    } 
} 
+13

+1 per cerchi a mano libera – James

+1

Verifica le proprietà del progetto: sei sicuro che la configurazione di debug non sia stata modificata in "codice di ottimizzazione"? – phoog

+0

@phoog Grazie per il suggerimento. Ho appena controllato le proprietà del progetto e "Ottimizza codice" è deselezionato. – daveaglick

risposta

8

Quindi si tratta di un errore in PostSharp. Stavo usando PostSharp ma ho rimosso tutti gli aspetti dal mio codice e mi sono assicurato che nessuno fosse applicato. Ho anche verificato con Reflector che i metodi erano intatti nell'assemblaggio. Tuttavia, sembra semplicemente fare riferimento a PostSharp che innesca un tipo di manipolazione dei simboli di debug che causa questo problema.A (poco) più informazioni possono essere trovate qui:

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

Inoltre, nelle note di rilascio per le ultime stati Hotfix PostSharp uno dei problemi risolti in hotfix 2.1.5.6 è "simboli di debug: simboli di variabili locali perso in iteratori impliciti. "

Quando ho installato PostSharp il più recente e migliore, il problema è andato via e l'universo è tornato alla normalità. Speriamo che questa domanda/risposta possa aiutare qualcun altro a utilizzare PostSharp che si imbatte in questo strano comportamento prima della prossima versione ufficiale di PostSharp. Assicurati di essere sull'hotfix 2.1.5.6 o successivo (data la gravità del bug, probabilmente questa dovrebbe essere una versione reale).

Grazie per tutto l'aiuto di tutti.

+1

buono a sapersi ... e contento che non sia un bug in VS 2010 – Yahia