La interrupción de Visual Studio 2015 en excepciones no controladas no funciona

114

Visual Studio solía tener una casilla de verificación específica para "Romper en excepción no controlada". En 2015, esto se eliminó (o se movió a algún lugar donde no puedo encontrarlo). Entonces, ahora mis proyectos convertidos ya no se rompen si no proporciono un controlador de excepciones a nivel de usuario. No quiero interrumpir todas las "excepciones lanzadas" porque manejo algunas específicas. Justo donde no puedo proporcionar un controlador específico.

En este momento, mi código simplemente sale del procedimiento actual y continúa la ejecución en la siguiente ubicación de la pila de llamadas, NO ES BUENO.

¿Alguien sabe cómo recuperar esto en Visual Studio 2015? Ayer me actualicé a la edición comunitaria.

Ted Lowery
fuente
Visual Studio 2015 mantendrá el diseño actual de su versión anterior, si no, la pestaña Toolo Windowtendrá todas las ubicaciones deseadas. En su caso, está buscando Configuración de excepción .
Greg
4
@greg, no es que no sepa dónde encontrar el panel. Mi preocupación es que el comportamiento que estoy buscando no está en ese panel.
Ted Lowery
el mismo problema aqui. En nuestro caso, esperamos una ruptura de excepción cuando autofac no tiene todos los tipos registrados. Usando la misma solución con vs2013 funciona, en vs2015 no obtenemos nada. esto también es un problema con otros registros y excepciones de terceros (como nservicebus) .Me pregunto si solo es el caso del proyecto creado en vs2013 y ejecutado en vs2015
Choco Smith
3
Esa nueva ventana de herramientas realmente apesta.
cedd
De acuerdo con las clasificaciones de excepciones de MS, si tiene una excepción no controlada , siempre se rompe el depurador. Puede que tengas que marcar la opción "Interrumpir cuando las excepciones crucen AppDomain ..." en la lista "Opciones -> Depuración -> General".
tsul

Respuestas:

118

Hay una nueva ventana llamada "Configuración de excepciones" que aparece en el panel inferior derecho de forma predeterminada cuando comienza a depurar. Tiene todas las opciones que cabría esperar.

Puedes mencionarlo con CTRL+ ALT+E

Esto le permite seleccionar qué excepciones causan una interrupción en el depurador.

Sin embargo, la clave es que también puede establecer si estas excepciones siempre se rompen o solo se rompen cuando se trata de una excepción no controlada, pero configurar esto no es muy intuitivo.

Primero deberá marcar "Habilitar solo mi código" en Herramientas> Opciones> Depuración.

Esto le permite hacer clic con el botón derecho en el encabezado de la columna (Interrumpir cuando se lanza) en la nueva ventana Configuración de excepciones y agregar la columna "Acciones adicionales", que luego le permite establecer cada excepción como "Continuar cuando no se maneja en el código de usuario".

Así que simplemente haga clic con el botón derecho en una excepción o en un grupo completo y desactive la marca "Continuar cuando no se maneja en el código de usuario". Desafortunadamente, la columna "Acciones adicionales" aparecerá vacía, lo que es lo mismo que "Romper cuando no se maneja en el código de usuario".

ingrese la descripción de la imagen aquí

Más sobre esto aquí:

http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

Tom Studee
fuente
7
En realidad, esa ventana solo tiene opciones para "romper con arrojado". Eso no es lo que quiero. Quiero "romper cuando no se maneja".
Ted Lowery
17
Y ese es el problema. NO se rompe. como dije anteriormente, sale (sale) de la llamada al procedimiento actual y simplemente comienza a ejecutar la siguiente línea de código en el procedimiento de llamada.
Ted Lowery
2
y SÍ tengo habilitado "Solo mi código".
Ted Lowery
19
@TomStudee Yo también tengo el mismo problema. Lo que quiero es "Romper cuando no se maneja", pero lo que obtengo es "Romper cuando se lanza". La pregunta es: ¿cómo conseguir "Romper cuando no se maneja"?
ogggre
1
@TomStudee Acabo de agregar una aclaración muy necesaria, ya que le faltaba la configuración clave que le permite establecer excepciones para que se rompan solo cuando no se controlan.
Jerad Rose
36

Tuve el mismo problema y logré resolverlo haciendo esto:

  1. Presione Ctrl+ Alt+ epara abrir la ventana Configuración de excepciones .
  2. Marque Excepciones de tiempo de ejecución de lenguaje común . ingrese la descripción de la imagen aquí

¡Eso es!

Me inspiré en esta publicación porque estoy usando una versión x64 de Windows .

Justin XL
fuente
7
Eso hará que se interrumpa en todas las excepciones, incluso en aquellas manejadas por código de usuario.
carlin.scott
1
@ carlin.scott, creo que podría desmarcar manualmente las excepciones que se manejan en la lista.
Justin XL
6
@JustinXL El problema es que esta es una lista por tipo de excepción, no por si se maneja o no. Por ejemplo, hay ocasiones en las que System.ArgumentExceptionse maneja y otras en que no. Solo me importa romper cuando no se maneja.
Jerad Rose
1
@JeradRose El depurador siempre se interrumpirá cuando no se controle una excepción. Entonces, como dije, si no desea interrumpir las excepciones manejadas, simplemente desmarque los tipos de excepción de la lista Break When Thrown .
Justin XL
Incluso cuando se verifica todo, no se está rompiendo en una excepción: / solo saliendo
Douglas Gaskell
10

Para los usuarios de Google que quieren romper solo cuando la excepción se refiere a su código, hay una opción en Visual Studio 2015: Opciones-> Depuración-> General-> Solo mi código. Una vez marcado, permite que no se rompa cuando la excepción se gestiona (lanza y captura) fuera de su código.

Olivier de Rivoyre
fuente
Esto me salvó para otra situación en la que VS2015 por alguna razón se negó a ingresar algún código. El código es "mío" pero algo activó la bandera "Solo mi código". Supongo que hay un error en alguna parte al ejecutar 2 instancias de VS y un servidor web independiente y probablemente algunas más.
LosManos
9

Microsoft ha cambiado sutilmente la lógica en la nueva ventana de excepciones.

Ver http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

La parte clave es:

Notas importantes

  • Esta nueva ventana contiene todas las mismas funciones que el diálogo modal anterior. Ninguna capacidad del depurador ha cambiado solo la forma en que puede acceder a ellas
  • El depurador siempre se interrumpirá cuando no se controle una excepción
  • La configuración para cambiar si el depurador se interrumpe en las excepciones no controladas por el usuario se ha movido a un menú contextual
  • La ubicación del menú se ha movido a Depurar -> Windows -> Configuración de excepción

Sin embargo , si, como yo, tiene un Controlador de excepciones no manejado global en su código, entonces el segundo elemento de esa lista es clave: para mí, por lo tanto, ninguna excepción quedará realmente sin manejar, lo que parece ser diferente de VS2013.

Para recuperar el comportamiento en el que VS se interrumpe en las excepciones no controladas, tuve que marcar todos los tipos de excepción en los que quería interrumpir y luego, en segundo lugar, asegurarme de que las "Opciones adicionales" (es posible que deba hacer que esta columna sea visible *) para "Continuar cuando no se maneja en el código de usuario " NO se configuró. La lógica VS2015 no parece considerar que mi Controlador de excepciones no manejadas global se "maneje en el código de usuario", por lo que se rompe en estos; sin embargo, no se rompe en excepciones detectadas. Esto hace que funcione como lo hizo VS2013.

* Cómo habilitar la columna "Acciones adicionales" * Cómo habilitar la columna "Acciones adicionales"

avena
fuente
2
Esto no funciona exactamente como VS2013 porque se interrumpirá en las excepciones manejadas por el usuario con la configuración que ha sugerido, lo que no era el caso en el pasado.
carlin.scott
¿Cómo se hace visible la columna "Opciones adicionales"?
UuDdLrLrSs
@DaveInCaz Haga clic con el botón derecho en el encabezado de la columna> "Mostrar columnas"> "Acciones adicionales"
oatsoda
7

Si estoy leyendo correctamente entre líneas aquí, el problema es que su excepción está efectivamente 'desapareciendo' a pesar de que el comportamiento del depurador predeterminado debería fallar en las excepciones no controladas.

Si tiene métodos asincrónicos, es posible que se encuentre con este problema porque las excepciones que no se detectan en un subproceso de grupo de subprocesos como parte de una continuación de Tarea no se consideran excepciones no controladas. Por el contrario, se ingieren y almacenan con la tarea.

Por ejemplo, eche un vistazo a este código:

class Program
{
    static void Main(string[] args)
    {
        Test();
        Console.ReadLine();
    }

    private async static Task Test()
    {
        await Task.Delay(100);
        throw new Exception("Exception!");
    }
}

Si ejecuta este programa con la configuración predeterminada del depurador (se detiene solo en excepciones no controladas), el depurador no se interrumpirá. Esto se debe a que el subproceso del grupo de subprocesos asignado a la continuación se traga la excepción (pasándola a la instancia de Task) y se libera de nuevo al grupo.

Tenga en cuenta que, en este caso, el problema real es que nunca se comprueba lo Taskdevuelto por Test(). Si tiene tipos similares de lógica de 'disparar y olvidar' en su código, entonces no verá las excepciones en el momento en que se lanzan (incluso si están 'no controladas' dentro del método); la excepción solo aparece cuando observa la Tarea esperándola, verificando su Resultado o mirando explícitamente su Excepción.

Esto es solo una suposición, pero creo que es probable que estés observando algo como esto.

Dan Bryant
fuente
Aunque esto puede no estar relacionado con el problema de la operación, plantea un muy buen punto sobre las excepciones que surgen en las rutinas asíncronas.
Phil Cooper
¿Hay alguna manera de hacer que el depurador se detenga aunque la excepción se almacene así?
Lucas
@Lucas, no que yo sepa, aunque puedes acercarte con algunos cambios de código. Si el cuerpo de su método disparar y olvidar tiene un bloque try-catch, puede agregar una Debugger.Break()llamada explícita . Alternativamente, puede agregar un explícito Debugger.Break()en el TaskScheduler.UnobservedTaskExceptioncontrolador, aunque la desventaja aquí es que esto puede activarse mucho más tarde que la excepción original, como sucede en el subproceso del finalizador cuando se limpia la Tarea. En general, debe esforzarse por observar siempre los resultados de la tarea o al menos tener un bloque try-catch para registrar en el momento del error.
Dan Bryant
3

En mi experiencia, la configuración de excepciones en 2015 se desequilibra completamente si cambia algo.

Espere que si llega al grupo principal "CLR", no debería obtener ningún execpt de ruptura por no controlado. Siempre fallará si una excepción no se maneja. Pero, si tiene el grupo CLR sin marcar, el código dentro de un try ... catch simplemente no debería causar una interrupción. Ese no es el caso.

Solución: en la nueva caja de herramientas de configuración de excepciones, haga clic con el botón derecho y seleccione "restaurar predeterminado". Taadaaaa ... Se comporta normalmente de nuevo. Ahora no lo jodas.

Clint StLaurent
fuente
1

Intente seguir las instrucciones:

  1. En la ventana Configuración de excepciones, abra el menú contextual haciendo clic con el botón derecho en la ventana y luego seleccionando Mostrar columnas. (Si ha desactivado Just My Code, no verá este comando).
  2. Debería ver una segunda columna denominada Acciones adicionales. Esta columna muestra Continuar cuando no lo controla el código de usuario en excepciones específicas, lo que significa que el depurador no se interrumpe si esa excepción no se maneja en el código de usuario sino en un código externo.
  3. Puede cambiar esta configuración para una excepción en particular (seleccione la excepción, haga clic con el botón derecho y seleccione / anule la selección de Continuar cuando no se maneje en el código de usuario) o para una categoría completa de excepciones (por ejemplo, todas las excepciones de Common Language Runtime).

https://msdn.microsoft.com/en-us/library/x85tt0dd.aspx

Andrei
fuente
Totalmente de acuerdo. Es terrible no mostrar esta columna por defecto. Pasó mucho tiempo para encontrarlo. Además, lo que significa " excepción no controlada por el usuario " no está claro. Tenía mi controlador de una cancelación de tarea (algo así como try { task.Wait(); } catch { ... }) y OperationCanceledException en la tarea se consideraba no manejada en el código de usuario de alguna manera.
tsul
1

Todo es un poco confuso y, en mi opinión, no es tan bueno como el antiguo diálogo de excepciones, pero de todos modos.

Si hay una excepción en la lista y está marcada, el depurador se interrumpirá cada vez que se lance la excepción.

Si una excepción no está marcada o no está en la lista, el depurador solo se interrumpirá cuando el usuario no controle ese tipo de excepción.

Por ejemplo, en la captura de pantalla a continuación, el depurador se interrumpirá cada vez que System.AccessViolationExceptionse lance un, pero para todas las demás excepciones, solo se interrumpirá si el usuario no manejó la excepción.

Ventana de la herramienta de excepciones de Visual Studio 2015

cedd
fuente
1

Cuando actualicé a VS2015, también tuve problemas en los que las excepciones solían "romper" la aplicación, pero ahora se ignoran y se pasan por alto. Hay ocasiones en las que queremos que nuestro código genere excepciones intencionalmente en lugares donde queremos que el código se detenga, en lugar de continuar. Siempre usamos la frase Throw New Exception("Message")para que nuestro código se rompa intencionalmente:

    If SomethingReallyBad = True Then
        Throw New Exception("Something Really Bad happened and we cannot continue.")
    End If

Con VS2015, el clásico "System.Exception" es lo que se lanza cuando decimos Throw New Exception. Por lo tanto, necesitábamos marcar la marca "System.Exception" en la nueva configuración de excepciones:

Marque la casilla System.Exception

Una vez comprobado, nuestro código funcionó como se esperaba.

J. Wyckoff
fuente
1

La solución es semánticamente opuesta a lo que crees que estás configurando. Debe asegurarse de que Continuar cuando no se maneja en el código de usuario no esté habilitado, es decir, no esté marcado como se muestra en la columna Acciones adicionales en la pestaña Configuración de excepciones ; consulte a continuación:

efectivamente está diciendo no continuar (es decir, romper) cuando no se maneja en el código

Ventana de configuración de excepciones (Control + Alt + E)

Para hacer esto:

  1. Haga clic con el botón derecho en la excepción o el conjunto de excepciones que le interesan (es decir, generalmente en la línea superior 'Excepciones de tiempo de ejecución de lenguaje común' en el árbol)
  2. Seleccione la opción Continuar cuando no se maneja en el código de usuario (ver más abajo)
  3. Asegúrese de que las excepciones no estén marcadas (ver más abajo)
  4. continuar depurando

ingrese la descripción de la imagen aquí

Eso fue por mí, feliz de nuevo.

Esto fue en VS 2015

Simon Sanderson
fuente
0

Definitivamente hay algún error en Visual Studio que puede hacer que se atasque y sea necesario reiniciar. Incluso VS2015.

Tuve una situación de un solo hilo en la que un NullReferenceExceptioncontrolador 'externo' (todavía en mi código) atrapaba a a pesar de que pedí que se rompiera cuando se generó.

Me doy cuenta de que esta es una excepción 'manejada' y estás hablando de una 'no manejada'; sin embargo, estoy bastante seguro de que a veces un reinicio rápido de VS solucionará esto, si IISRESET no lo hace.

Simon_Weaver
fuente
0

Visual Studio 2017 funciona bien con el manejo de errores. Visual Studio 2015, por otro lado, apesta en el manejo de errores con tareas porque en el modo de depuración se detectan todas las excepciones que ocurren en una tarea asíncrona, pero luego, si paso por encima, simplemente se cuelga indefinidamente. Si se ejecuta sin depurar, se cuelga indefinidamente sin excepción. Me encanta Visual Studio y lo he estado usando desde 1995 y 2015 es la peor versión con diferencia, aunque salté de 2010 directamente a 2015. Pasé 8 horas tratando de que este manejo de excepciones funcionara sin éxito. Copié el código exacto a 2017 en la computadora de mi casa y funcionó perfectamente. Me irrita mucho que Microsoft haya introducido tareas en un marco que el compilador de 2015 no puede manejar correctamente.

Moisés
fuente