Cuando estoy depurando algo que sale mal dentro de un bucle, por ejemplo en la iteración número 600, puede ser difícil tener que romper para cada uno. Así que traté de establecer un punto de corte condicional, para romper solo si I = 600. Eso funciona, pero ahora se tarda casi un minuto completo en llegar a ese punto, donde antes era casi instantáneo. ¿Qué está pasando, y hay alguna manera de solucionarlo?¿Por qué los puntos de interrupción condicionales ralentizan tanto mi programa?
Respuesta
Los puntos de interrupción condicionales en cualquier depurador (estoy suponiendo aquí) requieren que el proceso se mueva hacia atrás y hacia adelante cada vez entre su programa y el depurador cada vez que se golpea el punto de interrupción. Este proceso lleva mucho tiempo, pero no creo que haya nada que puedas hacer.
Cuando llega a un punto de interrupción, Windows detiene el proceso y notifica al depurador. Tiene que cambiar contextos, evaluar la condición, decidir que no, no desea que se le notifique, reiniciar el proceso y volver atrás. Eso puede tomar muchos ciclos de procesador. Si lo haces en un circuito cerrado, tomará un par de órdenes de magnitud más de ciclos de procesador que una iteración del ciclo.
Si está dispuesto a meterse con su código un poco, hay una manera de hacer puntos de interrupción condicionales sin incurrir en todos estos gastos generales.
if <condition here> then
asm int 3 end;
Ésta es una instrucción de montaje sencillo que envía manualmente una notificación punto de interrupción en el sistema operativo. Ahora puede evaluar su condición dentro del programa, sin cambiar contextos. Solo asegúrate de volver a sacarlo cuando termines con él. Si un int 3 se activa dentro de un programa que no está conectado a un depurador, se generará una excepción.
Normalmente, los puntos de interrupción funcionan insertando la instrucción de interrupción apropiada en el código y luego verificando las condiciones que ha especificado. Verificará en cada iteración y bien podría ser que la forma en que se implementa el cheque sea responsable de la demora, ya que es poco probable que el depurador compile e inserte el código completo de verificación y punto de interrupción en el código existente.
Una forma en que puede acelerar esto es si pone la condición seguida de una operación sin efectos secundarios en el código directamente y rompe esa operación. Solo recuerde eliminar la condición y la operación cuando haya terminado.
Probablemente no sea la comprobación condicional en sí misma, sino los cambios de contexto y la sobrecarga de detener y reiniciar el proceso. No se da cuenta de que con un punto de interrupción normal ya que aterriza en el depurador de todos modos, pero en un punto condicional donde continúa, se vuelve muy aparente muy rápidamente. –
Se ralentiza porque cada vez que llega a ese punto, tiene que verificar su condición.
Lo que suelo hacer es crear temporalmente otra variable como esta (en C pero debería ser posible en Delphi).
int xyzzynum = 600;
while (true) {
doSomething();
if (--xyzzynum == 0)
xyzzynum = xyzzynum;
}
entonces puse un punto de interrupción no condicional en la línea "xyzzynum = xyzzynum;"
.
El programa se ejecuta a toda velocidad hasta que ha pasado por el bucle 600 veces, porque el depurador está haciendo una interrupción de punto de interrupción normal en lugar de comprobar las condiciones todo el tiempo.
Puede hacer que la condición sea tan complicada como desee.
+1 En este caso, el operador probablemente podría usar algo simple como si I = 600 y luego escribir; y poner un punto de interrupción en la cláusula de escritura. –
+1 para la referencia Colosal Caves. : D –
Las explicaciones de Mason son bastante buenas.
Su código se podría hacer un poco más seguro por la prueba que se ejecuta en el depurador:
if (DebugHook <> 0) and <your specific condition here> then
asm int 3 end;
Esto no va a hacer nada cuando la aplicación se está ejecutando normalmente y se detendrá si se está ejecutando en el depurador (ya sea lanzado desde el IDE o conectado al depurador).
Y con el acceso directo booleano <your specific condition here>
ni siquiera se evaluará si no está bajo el depurador.
Y también dará [Advertencia Pascal] Dist.dpr (72): W1002 El símbolo 'DebugHook' es específico de una plataforma, lo que facilita su búsqueda antes del check in. –
con la respuesta de Mason, que podría hacer que el int 3 Assember sólo puede ser compilado en si el programa está construido con la depuración condicional definido:
{$ifdef debug}
{$message warn 'debug breakpoint present in code'}
if <condition here> then
asm int 3 end;
{$endif}
lo tanto, cuando se está depurando en el IDE, usted tiene el condicional de depuración en las opciones del proyecto. Cuando construyes el producto final para tus clientes (¿con tu script de compilación?), No incluirías ese símbolo, por lo que no se compilará.
También incluí la directiva del compilador de $ mensajes, por lo que verás un advertencia cuando compila, haciéndole saber que el código aún está allí. Si haces eso en cualquier lugar donde uses int 3, entonces tendrás una buena lista de lugares en los que puedes hacer doble clic para llevarte directamente al código ofensivo.
N @
- 1. Puntos de interrupción condicionales no dependientes de la línea
- 2. ¿Por qué mi depurador C# omite puntos de interrupción?
- 3. ¿Por qué Eclipse CDT ignora los puntos de interrupción?
- 4. Cómo establecer puntos de interrupción condicionales en Visual Studio?
- 5. ¿Por qué duplican mis puntos de interrupción en Visual Studio?
- 6. ¿Por qué mi proyecto Eclipse tiene puntos de interrupción phantom depurador?
- 7. Xdebug ignora los puntos de interrupción
- 8. ¿Por qué tengo puntos de interrupción desconocidos en mi pestaña Marcadores?
- 9. ¿Por qué los elementos fijos ralentizan el desplazamiento en Firefox?
- 10. Eclipse Helios ignora los puntos de interrupción
- 11. Xcode + eliminar todos los puntos de interrupción
- 12. Visual Studio: recorriendo los puntos de interrupción
- 13. Establecimiento de puntos de interrupción en Java
- 14. Puntos de secuencia, condicionales y optimizaciones
- 15. ¿Las declaraciones preparadas ralentizan notablemente el programa?
- 16. clojurescript puntos de interrupción
- 17. ¿Cómo se agregan los puntos de interrupción a un programa de Python en IDLE?
- 18. ¿Por qué mi programa de sombreado OpenGL para puntos tiene artefactos de bandas?
- 19. Windbg Establecer puntos de interrupción condicionales que dependen de la Pila de llamadas
- 20. Xcode está parando a continuación automática los puntos de interrupción
- 21. ¿Por qué mi gema tarda tanto en cargarse?
- 22. gdb no llega a los puntos de interrupción
- 23. Puntos de interrupción páginas aspx
- 24. ¿Cómo se configuran automáticamente los puntos de interrupción en todos los métodos en XCode?
- 25. Puntos de interrupción de omisión de Eclipse
- 26. Por qué los puntos son lentos
- 27. ¿Dónde se guardan los puntos de interrupción de Visual Studio?
- 28. Ver todos los puntos de interrupción en Visual Studio 2010+
- 29. Flash Builder desactiva los puntos de interrupción (a veces)
- 30. Puntos de interrupción ininterrumpidas (puntos de rastreo) en Javascript?
Me figuré tanto jajaja pero lo ha dicho mejor. –
Mason: buen resumen; ten en cuenta que es fácil dejar algunas de estas construcciones en el código. Así que sugiero que se haga con algunas observaciones (utilizo algo con @@@) o macros, que tienen la garantía de no terminar en un producto real. – Adriaan
Esto está etiquetado como Delphi, que no tiene macros de preprocesador o @@@ observaciones. Una forma sencilla de asegurarse de no dejar ninguno es grep su base de código para "int 3" antes de crear una versión de lanzamiento. –