2011-03-14 32 views
194

Tengo una solución con algunos proyectos. Hay varios puntos de quiebre en diferentes proyectos. Quiero rastrear el primer hilo golpear uno de estos puntos de ruptura y continuar el seguimiento de ese único hilo a pesar de que otros hilos entren en los mismos bloques de código.¿Cómo depurar un único hilo en Visual Studio?

Sé que esto es posible mediante la definición de una condición en el punto de interrupción, es decir, nombre de hilo = ... o hilo Id = ... pero mi caso es una aplicación de carga pesada ASP.NET y tan pronto como me conecto a w3wp.exe muchos hilos llegarán a los puntos de quiebre. Necesito algo como un ThreadLocal<break-point>.

¿Es posible? ¿Si es así, cómo?

+0

¿Por qué intenta depurar en un servidor muy cargado? – Paolo

+5

@Paolo: esta aplicación web funciona como el corazón de una gran comunidad web y la situación de los errores es imposible de imitar en los escenarios de prueba. – Xaqron

+5

Vea el artículo * [Cinco consejos para depurar código de subprocesos múltiples en Visual Studio] (http://devpinoy.org/blogs/jakelite/archive/2009/01/10/5-tips-on-debugging-multi-threaded -code-in-visual-studio-net.aspx) *. – noproblem

Respuesta

110

Congelar/Descongelar hilos es una manera incorrecta porque otros hilos no ejecutan ningún código.

La forma más correcta y usable es:

  1. pulse Ctrl + A en la ventana de puntos de ruptura (seleccionar todos los puntos de interrupción).
  2. Haga clic derecho y seleccione "Filtrar ...".
  3. Ingrese "ThreadId = (identificación del hilo actual)".

En Visual Studio 2015 y más nuevo, el proceso es similar:

  1. pulse Ctrl + A en la ventana de puntos de ruptura (seleccionar todos los puntos de interrupción).
  2. Haga clic derecho y seleccione "Configuración ...".
  3. Marque "Condiciones" y seleccione "Filtro" en el menú desplegable
  4. Ingrese "ThreadId = (identificación del hilo actual)".

Así que todos los hilos se ejecutan, pero el depurador solo toca el hilo actual.

+1

Aunque no es exactamente lo que debería ser (todavía se necesita ThreadId como filtro), pero la solución más correcta con las opciones existentes. – Xaqron

+21

¿Impide esto que el comando de depuración "Paso" ingrese otros hilos? Ese fue un gran problema que tuve. Estoy caminando a través de mi hilo y de repente estoy en una porción de código completamente no relacionada. Ya no desarrollo en Visual Studio, así que no puedo probar. –

+4

Al hacer clic con el botón derecho en la ventana de puntos de interrupción no hay ningún comando de "filtro" ... y ¿cómo puede averiguar el Id. Actual de la secuencia de todos modos? - ¿Vas a la ventana inmediata y escribes 'System.Threading.Thread.CurrentThread.ManagedThreadId' o algo así? – BrainSlugs83

1

Sugeriría agregar otra instancia de la aplicación en el servidor activo, ya sea en el mismo hardware o en una máquina nueva (clústerlo) y luego depurar solo esa instancia. No agregaría un punto de interrupción en el código que los usuarios están desencadenando. Si no es una opción, agregaría más rastreo.

Sin embargo, si esto es absolutamente necesario y necesita una estadística de solución, estoy seguro de que podría agregar un punto de interrupción que se rompa solo si la solicitud proviene de su dirección IP. Para ello, agregue un punto de interrupción condicional que inspeccione HttpContext.Request.UserHostAddress. Sin embargo, tenga en cuenta que esto ralentiza considerablemente su aplicación.

+0

Eso es lo que he intentado. El problema es que esta instancia no funciona en el mismo dominio (ejecutándose en IP u otro dominio) y esto lleva a muchos problemas de certificado (SSL, WCF, ...) y también con poca carga la situación del buggy nunca ocurre. – Xaqron

+0

Disculpe, no estoy seguro de cuál de estos ha intentado, ¿ha probado el punto de interrupción condicional? – steinar

+0

Sí, los nombré en función de su Id administrado para garantizar la exclusividad. Entonces es difícil adivinar qué Id está asignado y establecer la condición en función de una conjetura. A veces, la suposición está cerca y, a veces, lleva mucho tiempo detectar el hilo. – Xaqron

284

Aquí es lo que hice:

  1. Establecer un punto de interrupción condicional que yo sólo conocía golpearía en el hilo que yo estaba buscando.

  2. Una vez que los éxitos de punto de interrupción y se encuentra en el hilo que desea, en la ventana de Visual Studio Hilos (durante la depuración, depuración -> Windows -> Hilos), Ctrl + Un (para seleccionar todas las discusiones) y luego Ctrl + haga clic en el hilo en el que se encuentra actualmente. Debería tener todos los hilos excepto el que desea depurar seleccionado.

  3. Haga clic derecho y elija "Congelar".

Ahora, Visual Studio solo atravesará el hilo descongelado. Parece ser mucho más lento al hacer esto, presumiblemente porque tiene que pasar por todos los hilos congelados, pero trajo un poco de cordura a mi depuración de subprocesos múltiples.

+44

Esto debería marcarse como la respuesta – Diego

+0

¡Justo lo que necesitaba! ¡Gracias! – KTF

+1

Esto no funciona para mí en un contexto en el que tengo aproximadamente 8 tareas ejecutándose en diferentes subprocesos. Congelé todos los otros hilos y "paso sobre" pero el IDE se congela por un tiempo, luego salta a otro hilo de todos modos. –

1

Si no desea detener todos los otros hilos (tal vez está adjuntando el depurador de Visual Studio a una aplicación en ejecución que necesita responder a las solicitudes), puede usar una macro que crea y elimina puntos de interrupción automáticamente.

Esto se sugiere en an answer to Stack Overflow question "Step over" when debugging multithreaded programs in Visual Studio.

Sin embargo, el enlace solo explica cómo depurar línea por línea. Sugiero que modifiques la macro (si te sientes cómodo con ella) para que modifique todos los puntos de interrupción (en un rango de línea dado, por ejemplo) para detener solo en el hilo actual.

12

Acabo de lanzar una extensión de Visual Studio 2010+ que hace exactamente lo que está buscando. Y es gratis :).

Presentación

Esta extensión de Visual Studio agrega dos accesos directos y botones de la barra para permitir a los desarrolladores centrarse fácilmente en hilos individuales, mientras que la depuración de aplicaciones multihilo.

Reduce drásticamente la necesidad de acceder manualmente a la ventana de subprocesos para congelar/descongelar todos los hilos, pero el que se debe seguir y, por lo tanto, ayuda a mejorar la productividad.

Características

restringir aún más la ejecución para el hilo actual. Congelará todos los otros hilos. Atajo: CTRL + T + T o botón copo de nieve. Cambia al siguiente hilo individual (basado en ID). Cambiará el hilo actual y congelará todos los otros hilos. Atajo: CTRL + T + J o botón Siguiente.

Check it out here on the Gallery, en el official page o la Github repository.

+0

¿Qué versión de VS estás usando? –

+0

Instalé la extensión, pero no lo pude hacer funcionar (para mi proyecto actual, uso VS2010). [Por cierto, lo que pensé que era un problema con los subprocesos que se activan simplemente sucede cuando se crean los hilos, es probable que sea un comportamiento estándar, así que eliminé mi comentario anterior]. – wil

+0

Voy a verificar esto. Puede ser la única persona en el planeta que ha intentado resolver uno de los mayores fallos de depuración de Microsoft. – stu

8

Un poco enfoque diferente, que he utilizado:

  1. Crear un punto de interrupción normal y dejar que se golpeó
  2. mirada en la ventana de hilos para el ID de subproceso administrado que eres de depuración actual
  3. Haga clic derecho en el punto de interrupción en el filtro de ventana de puntos de ruptura y selecter
  4. Introduzca ThreadId = xxx donde xxx es el ID del hilo de 2
  5. Ahora puede depurar sin detener otros hilos y sin que lleguen a su punto de interrupción

Esto supone que tiene tiempo para hacer lo anterior antes de que un segundo hilo llegue a su punto de interrupción. Si no, y otros hilos llegan a su punto de interrupción antes de que haya hecho lo anterior, puede hacer clic con el botón derecho en la ventana de hilos y elegir congelar.

+1

+1. "Esto supone que tienes tiempo ... antes de que un segundo hilo llegue a tu punto de ruptura". Envuelvo un punto y coma en un candado y pongo un punto de corte en el punto y coma. Cuando se alcanza el punto de interrupción la primera vez, deshabilito el punto de interrupción. No pueden entrar otros hilos debido al bloqueo. 'lock (m_someObject) {; } ' – bluedog

6

Si se generan varios subprocesos como para una aplicación web, la respuesta de @MattFaus no funcionará. lo que hice en su lugar es el siguiente

  • Configure un punto de interrupción para interrumpir el hilo en la función que quiero.
  • Una vez que el subproceso llega al punto de interrupción y se pausa, elimino el punto de interrupción y continúo depurando con F8, F10 y F11, para que se puedan ejecutar los otros subprocesos.
+0

Aftre leyendo todos los principales comentarios, esta solución funcionó para mí. –

0

Creo que esto es un poco diferente en Visual Studio 2015. Han cambiado algunas cosas en los puntos de ruptura, pero aquí es cómo aplicar la respuesta aceptada de hzdbyte (arriba):

En el punto de interrupción en el margen de codificación, haga clic con el botón derecho en> Condiciones> Cambiar de 'Expresión condicional' a 'Filtro'. Esto luego le permite filtrar por ThreadId.

Alternativamente en el punto de interrupción en la ventana de Puntos de corte, haga clic con el botón derecho> Configuración> marque el cuadro Condiciones y haga lo anterior.

Cuestiones relacionadas