c# .net debugging optimization compiler-construction

c# - ¿Qué significa "No se puede evaluar la expresión porque el código del método actual está optimizado"? ¿Qué significa?



.net debugging (15)

Escribí un código con mucha recursión, que lleva bastante tiempo completar. Cada vez que "pause" la carrera para ver qué sucede, obtengo:

No se puede evaluar la expresión porque el código del método actual está optimizado.

Creo que entiendo lo que eso significa. Sin embargo, lo que me desconcierta es que después de dar el paso, el código ya no está "optimizado" y puedo mirar mis variables. ¿Como sucedió esto? ¿Cómo puede el código cambiar entre códigos optimizados y no optimizados?


Asegúrate de no tener algo así

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

en su AssemblyInfo


Busque una llamada a función con muchos params e intente disminuir el número hasta que vuelva la depuración.


Creo que lo que está viendo es el resultado de las optimizaciones, a veces se reutilizará una variable, especialmente las que se crean en la pila. Por ejemplo, supongamos que tiene un método que usa dos enteros (locales). El primer entero se declara al inicio del método y se utiliza únicamente como contador de un ciclo. Su segundo número entero se usa después de completar el ciclo, y almacena el resultado de un cálculo que luego se escribe en el archivo. En este caso, el optimizador PUEDE decidir reutilizar su primer entero, guardando el código necesario para el segundo entero. Cuando intenta ver el segundo entero al principio, aparece el mensaje que pregunta acerca de "No se puede evaluar la expresión". Aunque no puedo explicar las circunstancias exactas, es posible que el optimizador transfiera el valor del segundo entero a un elemento de la pila por separado más adelante, lo que le permite acceder al valor del depurador.



El depurador usa FuncEval para permitirle "mirar" las variables. FuncEval requiere que los subprocesos se detengan en código administrado en un punto seguro GarbageCollector. Al "pausar" manualmente la ejecución en el IDE, todos los hilos se detienen lo antes posible. Su código altamente recursivo tenderá a detenerse en un punto inseguro. Por lo tanto, el depurador no puede evaluar expresiones.

Presionando F10 se moverá al siguiente punto seguro de Funceval y se habilitará la evaluación de la función.

Para más información, revise las reglas de FuncEval .


El siguiente trabajó para mí, gracias @Vin.

Tuve este problema cuando estaba usando VS 2015. Mi solución: la configuración tiene (Debug) seleccionada. Resolví esto desmarcando la propiedad Optimize Code debajo de las propiedades del proyecto.

Proyecto (clic derecho) => Propiedades => Construir (pestaña) => desmarcar código de Optimizar


En mi caso, tenía 2 proyectos en mi solución y estaba ejecutando un proyecto que no era el proyecto de inicio. Cuando lo cambié al proyecto de inicio, la depuración comenzó a funcionar nuevamente.

Espero que ayude a alguien.


Esto me volvió loco. Intenté adjuntarme con código administrado y nativo, no ir.

Esto funcionó para mí y finalmente pude evaluar todas las expresiones:

  • Ir a Proyecto / Propiedades
  • Seleccione la pestaña Generar y haga clic en Avanzado ...
  • Asegúrese de que la información de depuración esté configurada como "completa" (no solo pdb)
  • Depure su proyecto - ¡voila!

Evaluación:

En .NET, "Function Evaluation (funceval)" es la capacidad de CLR para inyectar una llamada arbitraria mientras el depurador se detiene en alguna parte. Funceval se hace cargo del hilo elegido por el depurador para ejecutar el método solicitado. Una vez que termina funceval, se activa un evento de depuración. Técnicamente, CLR ha definido formas para que el depurador emita un funceval.

CLR permite iniciar funceval solo en aquellos subprocesos que están en el punto de seguridad del GC (es decir, cuando el subproceso no bloqueará el GC) y el punto de Funceval Safe (FESafe) (es decir, donde CLR puede realmente secuestrar el funceval) juntos. Por lo tanto, posibles escenarios para CLR, un hilo debe ser:

  1. detenido en código administrado (y en un punto seguro de GC): Esto implica que no podemos hacer un funceval en el código nativo. Como el código nativo está fuera del control del CLR, no puede configurar el funceval.

  2. detenido en una primera oportunidad o excepción gestionada no controlada (y en un punto seguro de GC): es decir, en el momento de la excepción, inspeccionar tanto como sea posible para determinar por qué ocurrió esa excepción. (Por ejemplo: el depurador puede intentar evaluar y ver la propiedad del mensaje en la excepción planteada).

En general, las formas comunes de detenerse en el código administrado incluyen detenerse en un punto de interrupción, paso, llamada a Debugger.Break, interceptar una excepción o al inicio de un hilo. Esto ayuda a evaluar el método y las expresiones.

Posibles soluciones: según la evaluación, si el subproceso no está en los puntos FESafe y GCSafe, CLR no podrá secuestrar el subproceso para iniciar funceval. En general, el siguiente ayuda para asegurarse de que funceval se inicia cuando se espera:

Paso 1:

Asegúrese de no intentar depurar una compilación de "Liberación". La versión está completamente optimizada y, por lo tanto, dará lugar al error en la discusión. Al usar la barra de herramientas Estándar o el Administrador de Configuración, puede alternar entre Depurar y Liberar.

Paso 2:

Si aún obtiene el error, la opción Depurar se puede configurar para la optimización. Verifique y desmarque la propiedad "Optimizar código" en Proyecto "Propiedades":

Haga clic derecho en la opción de selección de proyectos "Propiedades" Ir a la pestaña "Crear" Desmarque la casilla de verificación "Optimizar código"

Paso 3:

Si aún obtiene el error, el modo de información de depuración podría ser incorrecto. Verifique y configúrelo como "completo" en "Configuración avanzada de compilación":

Haga clic con el botón derecho en la opción Seleccionar proyecto "Propiedades" Vaya a la pestaña "Crear" Haga clic en el botón "Avanzado" Establezca "Información de depuración" como "completa"

Etapa 4:

Si aún enfrenta el problema, intente lo siguiente:

Haga una "Limpieza" y luego una "Reconstrucción" de su archivo de solución Durante la depuración: Vaya a la ventana de módulos (Menú VS -> Depurar -> Windows -> Módulos) Busque su ensamblaje en la lista de módulos cargados. Compruebe que la ruta indicada en el ensamblaje cargado es lo que usted espera. Compruebe la marca de tiempo modificada del archivo para confirmar que el ensamblaje fue realmente reconstruido. Compruebe si el módulo cargado está optimizado o no.

Conclusión:

No es un error, sino una información basada en ciertas configuraciones y diseñada en función del funcionamiento del tiempo de ejecución de .NET.


Mientras que la línea Debug.Break () está en la parte superior de la pila de llamadas, no puede evaluar expresiones. Eso es porque esa línea está optimizada. Presione F10 para pasar a la siguiente línea, una línea válida de código, y el reloj funcionará.


Probablemente esté intentando depurar su aplicación en modo de lanzamiento en lugar de depurar, o tiene activadas las optimizaciones en su configuración de compilación.

Cuando el código se compila con optimizaciones, ciertas variables se descartan una vez que ya no se utilizan en la función, y es por eso que recibe ese mensaje. En el modo de depuración con optimizaciones desactivadas, no debería obtener ese error.


Tuve este problema cuando estaba usando VS 2010. Mi configuración de solución tiene (Debug) seleccionada. Resolví esto desmarcando la propiedad Optimizar código debajo de las propiedades del proyecto. Proyecto (clic derecho) => Propiedades => Construir (pestaña) => desmarcar código de Optimizar


Tuve un problema similar y se resolvió cuando construí la solución en modo de depuración y reemplacé el archivo pdb en la ruta de ejecución.


Tuvo el mismo problema, pero pude resolverlo desactivando la captura de excepciones en el depurador. Haga clic en [Depurar] [Excepciones] y establezca las excepciones en "Usuario no controlado".

Normalmente tengo esto apagado, pero es útil de vez en cuando. Solo necesito recordar apagarlo cuando termine.


en mi caso yo estaba en modo de liberación unos cambié para depurarlo todo funcionó