visual todos studio simbolo quitar puntos punto puede porque ningun modo los interrupción interrupcion ignoro generado establecer encuentra encontro codigo cargado aplicacion actualmente activará c# .net visual-studio debugging breakpoints

c# - simbolo - quitar todos los puntos de interrupción visual studio



Un caso curioso de depurador de Visual Studio 2010(no puede alcanzar un punto de ruptura) (6)

Cambia la configuración de tu compilación a "Depurar", en lugar de "Liberar".

Un caso curioso de depurador de Visual Studio 2010 (no puede alcanzar un punto de ruptura)

Este es el código que reproduce el problema:

class Program { static void Main(string[] args) { bool b = false; if (b) { List<string> list = new List<string>(); foreach (var item in list) { } } else { Console.WriteLine("1"); } Console.WriteLine("2");//add a break point here in VS2010 } //1. configuration: release //2. platform target: x64 or Any Cpu //3. debug info: pdb only or full //4. OS: Win7 x64 //5. optimize code: enabled }

Agregue un punto de ruptura a la última declaración del código, luego depúrelo en vs2010, verá que no se puede alcanzar el punto de ruptura.

Para reproducir este curioso caso, deberás cumplir las siguientes condiciones:

  1. Sistema operativo: windows 7 x64;
  2. Configuración de compilación VS: lanzamiento;
  3. VS plataforma de construcción de destino: x64 o Cualquier Cpu;
  4. VS construye información de depuración: pdb solo o completo;
  5. Código de optimización de compilación VS: habilitado;

No estoy seguro de que esas condiciones sean suficientes para reproducirlo, pero es cómo se configuró mi máquina cuando encontré este problema.

¿Por qué el depurador no puede alcanzar el punto de interrupción?

¡Gracias por adelantado!

Y si puede reproducir este problema, considere votar en esta publicación.


Creo que cuando se realiza una depuración con el modo de liberación, es posible que sus puntos de interrupción no se correspondan con las líneas reales en el código porque el código de la máquina puede haber sido optimizado. En el caso de su código, en realidad no está haciendo ninguna parte de la impresión "1" y luego "2", por lo que sería seguro asumir que el compilador eliminaría el código de (b == falso) ya que nunca será alcanzado.


Cuando el ejemplo proporcionado está integrado en el modo de liberación y luego en JIT-ed en un código de máquina de 64 bits, no contiene suficiente información para que el depurador correlacione el punto de interrupción con ninguna instrucción de máquina en particular. Es por eso que el depurador nunca se detiene en este punto de interrupción durante la ejecución de un código de máquina JIT-ed. Simplemente no sabe dónde parar. Probablemente se trate de algún tipo de mal comportamiento o incluso de un error en el depurador CLR de 64 bits, ya que solo se puede reproducir cuando se procesa mediante JIT en un código de máquina de 64 bits, pero no en un código de máquina de 32 bits.

Cuando el depurador ve un punto de interrupción en su código, intenta encontrar una instrucción de máquina en el código JIT que corresponde a la ubicación marcada por el punto de interrupción. Primero, debe encontrar una instrucción IL que corresponda a una ubicación de punto de interrupción en su código C #. Entonces necesita encontrar una instrucción de máquina que corresponda al comando IL. Luego establece un punto de ruptura real en la instrucción de la máquina encontrada y comienza la ejecución del método. En su caso, parece que el depurador simplemente ignora un punto de interrupción porque no puede asignarlo a una instrucción de máquina en particular.

El depurador no puede encontrar la dirección de una instrucción de máquina que sigue inmediatamente a la sentencia if ... else. La instrucción if ... else y el código en su interior de alguna manera causan este comportamiento. No importa qué declaración sigue el if ... else. Puede reemplazar la declaración de Console.WriteLine (“2”) con otra y podrá seguir reproduciendo el problema.

Verá que el compilador de C # emite un bloque try ... catch alrededor de la lógica que lee la lista si va a desmontar el ensamblaje resultante con Reflector. Es una característica documentada del compilador de C #. Puedes leer más sobre esto en la declaración de foreach

Un intento ... captura ... finalmente el bloque tiene un efecto bastante invasivo en un código JIT-ed. Utiliza el mecanismo de Windows SEH debajo del capó y reescribe mal tu código. No puedo encontrar un enlace a un buen artículo en este momento, pero estoy seguro de que puedes encontrar uno si estás interesado.

Es lo que pasa aquí. El intento ... finalmente se bloquea dentro de la instrucción if ... else hace que el depurador tenga problemas. Puedes reproducir tu problema con un código mucho más simple.

bool b = false; if (b) { try { b = true; } finally { b = true; } } else { b = true; } b = true;

Este código no llama a ninguna función externa (elimina el efecto de la incorporación del método propuesto por una de las respuestas) y compila directamente en IL sin ningún código adicional agregado por el compilador de C #.

Es reproducible solo en el modo de lanzamiento porque en el modo de depuración el compilador emite la instrucción IL NOP para cada línea de su código C #. La instrucción IL NOP no hace nada y es compilada directamente a la instrucción NOP de la CPU por el JITer que tampoco hace nada. La utilidad de esta instrucción es que puede ser utilizada por el depurador como un ancla para los puntos de interrupción, incluso si el resto del código es reescrito por el JITer.

Pude hacer que el depurador funcione correctamente colocando una instrucción NOP justo antes de la instrucción que sigue a if ... else.

Puede leer más sobre las operaciones de NOP y el proceso de mapeo del depurador aquí.

Puede intentar usar WinDbg y la extensión SOS para que examine la versión del método JIT-ed. Puede intentar examinar el código de máquina que genera JIT-er y tratar de entender por qué no puede asignar ese código de máquina a una línea particular de C #.

Aquí hay un par de enlaces sobre el uso de WinDbg para interrumpir el código administrado y obtener una dirección de memoria de un método JIT-ed. Creo que debería poder encontrar una manera de obtener el código JIT-ed para un método a partir de ahí: establecer un punto de interrupción en WinDbg para el código administrado , hoja de trucos SOS (.NET 2.0 / 3.0 / 3.5) .

También puede intentar informar un problema a Microsoft. Probablemente este es un error de depuración CLR.

Gracias por la interesante pregunta.


El compilador JIT utiliza técnicas de optimización que pueden causar esto.

Una de esas optimizaciones se denomina método de alineación , que puede ser responsable de este comportamiento.

No puedo decir exactamente ahora, porque estoy usando la computadora de otra persona ... pero usted puede probar eso:

1) Crea el siguiente método:

[MethodImpl(MethodImplOptions.NoInlining)] public static void MyMethod(string str) { str += "-CONCAT-STRING"; }

2) reemplace las llamadas a "Console.WriteLine" con solo "MyMethod"

3) Establezca el punto de interrupción y pruébelo.

4) Ahora, elimine el atributo "MethodImpl" del método "MyMethod".

//[MethodImpl(MethodImplOptions.NoInlining)] public static void MyMethod(string str) { str += "-CONCAT-STRING"; }

5) Ejecutar de nuevo, con el punto de interrupción en el mismo lugar.

6) Si se detiene en la primera ejecución, pero no en la segunda ejecución ... entonces esta es la razón.


La creación de la versión omite la creación de los símbolos de depuración, lo que en sí mismo es obvio.

Puede anular esto yendo a las propiedades de su proyecto. seleccione la configuración de lanzamiento y presione ''Avanzado'' en la pestaña Crear. Establezca la información de depuración al completo.


Usando VS2010 SP1, se detiene en la última línea si establece un punto de interrupción en el modo de liberación. Debería instalarlo realmente, menciona específicamente que corrige los problemas del depurador donde a veces se saltearían los puntos de interrupción (aunque no este caso específico).