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

StackOverflow https://stackoverflow.com/questions/131628

Pregunta

Escribí un código con mucha recursión, que lleva bastante tiempo en completarse. Cada vez que "haga una pausa" la carrera para ver lo que está pasando me sale:

  
    

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 que presioné el paso, el código no está optimizado " Ya no, y puedo mirar mis variables. ¿Como sucedió esto? ¿Cómo puede el código alternar entre código optimizado y no optimizado?

¿Fue útil?

Solución

El depurador utiliza FuncEval para permitirle " ver " variables FuncEval requiere que los subprocesos se detengan en el código administrado en un punto seguro de GarbageCollector. Manualmente " pausando " la ejecución en el IDE hace que todos los subprocesos se detengan tan pronto como sea posible. Su código altamente recursivo tenderá a detenerse en un punto inseguro. Por lo tanto, el depurador no puede evaluar expresiones.

Al presionar F10 se moverá al siguiente punto Funceval Safe y se habilitará la evaluación de la función.

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

Otros consejos

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

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

Cuando el código se compila con optimizaciones, ciertas variables se descartan una vez que ya no se usan en la función, por lo que está recibiendo ese mensaje. En el modo de depuración con las optimizaciones desactivadas, no debería recibir ese error.

Esto me volvió loco. Intenté adjuntar con código administrado y nativo: no continuar.

Esto me funcionó y finalmente pude evaluar todas las expresiones:

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

Lo de abajo me funcionó, gracias @Vin.

Tuve este problema cuando estaba usando VS 2015. Mi solución: la configuración ha seleccionado (Depurar). Resolví esto al desmarcar la propiedad Optimize Code en las propiedades del proyecto.

  

Proyecto (clic derecho) = > Propiedades = > Crear (pestaña) = > desmarque Optimizar código

Busque una llamada de función con muchos parámetros e intente disminuir el número hasta que la depuración vuelva.

Asegúrate de no tener algo así

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

en su AssemblyInfo

El amigo de un amigo de Microsoft envió esto: http://blogs.msdn.com/rmbyers/archive/2008/08/16/Func_2D00_eval-can-fail-while-stopped-in -a-non_2D00_optimized-managed-method-that-pushs-more-than-256-argument-bytes-.aspx

El problema más probable es que su pila de llamadas se esté optimizando porque la firma de su método es demasiado grande.

Tenía el mismo problema, pero fue capaz de resolverlo desactivando la captura de excepciones en el depurador. Haga clic en [Depurar] [Excepciones] y configure las excepciones en " Usuario no manejado " ;.

Normalmente tengo esto apagado pero es útil ocasionalmente. Solo necesito recordar apagarlo cuando termine.

Tuve este problema cuando estaba usando VS 2010. La configuración de mi solución ha seleccionado (Depurar). Resolví esto al desmarcar la propiedad Optimizar Código en las propiedades del proyecto. Proyecto (clic derecho) = > Propiedades = > Crear (pestaña) = > desmarque Optimizar código

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.

Evaluación:

En .NET, "Evaluación de función (funceval)" es la capacidad de CLR para inyectar una llamada arbitraria mientras el debuggee se detiene en algún lugar. Funceval se hace cargo del subproceso elegido por el depurador para ejecutar el método solicitado. Una vez que funceval termina, se dispara un evento de depuración. Técnicamente, CLR tiene formas definidas para que el depurador emita un valor funceval.

CLR permite iniciar funceval solo en aquellos subprocesos que se encuentran en el punto seguro del GC (es decir, cuando el subproceso no bloqueará el GC) y el punto Funceval Safe (FESafe) (es decir, donde CLR puede hacer el secuestro para el funceval). . Por lo tanto, los 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 código nativo. Como el código nativo está fuera del control de CLR, no puede configurar el funceval.

  2. se detuvo en una primera oportunidad o una excepción gestionada no controlada (y en un punto seguro de GC): es decir, en el momento de la excepción, para inspeccionar todo lo posible para determinar por qué se produjo esa excepción. (por ejemplo, el depurador puede intentar evaluar y ver la propiedad del mensaje en la excepción generada).

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

Posibles resoluciones: Según la evaluación, si el subproceso no está en los puntos FESafe y GCSafe, CLR no podrá secuestrar el subproceso para iniciar el funceval. En general, lo siguiente ayuda a garantizar que se inicie funceval cuando se espera:

Paso # 1:

Asegúrese de que no está intentando depurar una compilación "Release". El lanzamiento está totalmente optimizado y, por lo tanto, conducirá al error en la discusión. Al utilizar la barra de herramientas Estándar o el Administrador de configuración, puede cambiar entre Debug & amp; Lanzamiento.

Paso # 2:

Si aún recibe el error, la opción de depuración podría estar configurada para la optimización. Verificar & amp; Desmarque la propiedad "Optimizar código" en "Propiedades" del proyecto:

Haz clic derecho en el proyecto Seleccione la opción "Propiedades" Ir a la pestaña "Construir" Desmarque la casilla "Optimizar código"

Paso # 3:

Si aún recibe el error, el modo de información de depuración podría ser incorrecto. Verificar & amp; configúrelo como "completo" en "Configuración avanzada de compilación":

Haz clic derecho en el proyecto Seleccione la opción "Propiedades" Ir a la pestaña "Construir" Haga clic en el botón "Avanzado" Establecer "Información de depuración" como "completo"

Paso # 4:

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

Haz un "Limpio" & amp; luego una "Reconstrucción" de su archivo de solución Durante la depuración: Ir a la ventana de módulos (Menú VS - > Depurar - > Windows - > Módulos) Encuentra tu conjunto en la lista de módulos cargados. Verifique que la ruta indicada en el ensamblaje cargado es lo que espera que sea Verifique la marca de tiempo modificada del archivo para confirmar que el ensamblaje realmente fue 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 según se diseñó según el funcionamiento del tiempo de ejecución de .NET.

En mi caso, estaba en modo de versión. Cambié para depurar, todo funcionó

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

Creo que lo que está viendo es el resultado de las optimizaciones, a veces una variable se reutilizará, especialmente las que se crean en la pila. Por ejemplo, suponga que tiene un método que utiliza dos enteros (locales). El primer entero se declara al comienzo del método y se usa únicamente como contador para un bucle. Su segundo entero se usa después de que se haya completado el bucle, 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 desde el principio, recibe el mensaje que está preguntando sobre " 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 pila separado más adelante, lo que resultará en que luego pueda acceder al valor desde el depurador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top