2011-12-29 8 views
16

Tengo un problema muy extraño con las variables locales que están fuera de contexto en el depurador de Visual Studio 2010 para una aplicación de consola C# que se dirige a .NET 4.0. He buscado otras preguntas similares en SO, pero aunque algunas tienen los mismos síntomas, ninguna parece aplicarse directamente a este problema (todas parecen tener otras causas raíz).Variables fuera de contexto en Visual Studio 2010 Debugger

El problema es que para algunas variables (pero no todas) no recibo una información sobre herramientas con su valor, no aparecen en la ventana Locales, y obtengo "El nombre 'xyz' no existe en la corriente contexto "si los agrego a la ventana de observación. Parece afectar algunas variables pero no otras, y no puedo descifrar un patrón (no parece estar basado en miembro vs. local, clase vs. estructura, o cualquier otro diferenciador). He reiniciado mi computadora y Visual Studio, verificado que tengo una compilación limpia de depuración, me aseguré de que el marco de depuración sea correcto, me aseguré de actualizar las variables en la pantalla del reloj e intenté varios hechizos y conjuros.

He incluido una captura de pantalla a continuación (versión más grande en http://i.stack.imgur.com/JTFBT.png).

enter image description here

¿Alguna idea?

EDIT:

Agregando un poco de información adicional:

El problema es repetible. Las mismas variables exactas funcionan o no funcionan, incluso después de apagar completamente y reiniciar Visual Studio. Esto me lleva a creer que en realidad algo sistemático va mal en lugar de solo corrupción de memoria o algo así.

También descubrí que parece estar relacionado con el bloque try-catch. Si ubico el punto de interrupción fuera de la declaración try, puedo ver cualquiera de las variables dentro del alcance normalmente. Tan pronto como el punto de ejecución entre en la instrucción try, todas las variables fuera del bloque try se vuelven inaccesibles y solo puedo acceder a las que están dentro de la instrucción try. Es casi como si el depurador estuviera tratando el bloque try como un método separado (aunque puede ver que el código/compilador todavía tiene acceso a las variables dentro del alcance). ¿Alguien ha visto este comportamiento antes?

otra edición:

I (parcial) Retiro lo que dije sobre el try-catch ser sospechoso - parece que en esta parte del código de los objetos expuestos depurador esta extraña toma cosas fuera de contexto para cualquier encerramiento bloquear. Por ejemplo, si configuro un punto de interrupción directamente dentro de la declaración foreach en la captura de pantalla, puedo ver el valor de la variable "port" en cada iteración, pero ninguna de las variables fuera de la declaración foreach (que desaparecen tan pronto como ingreso al bloque foreach) . Luego, tan pronto como ingrese al bloque try, la variable "port" desaparecerá de repente. Esto se está poniendo realmente extraño.

Además, como se solicita, el código para todo el método está a continuación.

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 para círculos a mano alzada – James

+1

Compruebe las propiedades de su proyecto: ¿está seguro de que la configuración de depuración no se ha modificado para "optimizar el código"? – phoog

+0

@phoog Gracias por la sugerencia. Acabo de comprobar las propiedades del proyecto y "Deshabilitar código" está desmarcado. – daveaglick

Respuesta

8

Resulta que esto está relacionado con un error en PostSharp. He estado utilizando PostSharp, pero eliminé todos los aspectos de mi código y me aseguré de que no se aplicara ninguno. También verifiqué con Reflector que los métodos estaban intactos en el ensamblaje. Sin embargo, parece que simplemente haciendo referencia a PostSharp desencadena algún tipo de manipulación de los símbolos de depuración que causa este problema.A (poco) más información se puede encontrar aquí:

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

Además, en las notas de lanzamiento de nuevos estados de revisión PostSharp uno de los problemas corregidos en revisión 2.1.5.6 es "símbolos de depuración: Símbolos de variables locales perdido en iteradores implícitos ".

Cuando instalé el último y mejor PostSharp, el problema desapareció y el universo volvió a la normalidad. Con suerte, esta pregunta/respuesta ayudará a cualquier otra persona que utilice PostSharp que tropiece con este extraño comportamiento antes del próximo lanzamiento oficial de PostSharp. Asegúrese de estar en la revisión 2.1.5.6 o posterior (dada la gravedad del error, probablemente debería haber sido una versión real).

Gracias por toda la ayuda a todos.

+1

es bueno saberlo ... y me alegro de que no sea un error en VS 2010 – Yahia