Respuesta

12

Para detener en cualquier llamada a una función API, lo encuentran en la sección de implementationwindows.pas (o donde se declara la función de interés) y establecer un punto de interrupción. Eso se ocupa de las funciones que utiliza con enlaces dinámicos de tiempo de carga. Para el enlace dinámico en tiempo de ejecución (LoadLibrary y GetProcAddress), necesitará una técnica diferente. La variable que obtiene el resultado de GetProcAddress contendrá la dirección que desea interrumpir, pero no sé de antemano cómo establecer un punto de interrupción en esa dirección.

Parar en un mensaje de ventana es más complicado ya que los mensajes se pueden recuperar en muchos lugares. En su lugar, deberá usar puntos de interrupción condicionales.

Para captar la mayoría de los mensajes publicados, puede poner un punto de interrupción en TApplication.HandleMessage en la primera línea después de la llamada al PeekMessage. Establezca la condición para que sea Msg.Message = x. HandleMessage se ocupa de los mensajes publicados en la cola de mensajes del subproceso principal para el ciclo de mensaje principal Application.Run, así como los bucles de mensaje modal de la VCL. Sin embargo, otros diálogos modales (como Windows.MessageBox) no lo usarán.

Observar mensajes enviados es más difícil porque el sistema operativo los envía a sus procedimientos de ventana de destino directamente. Deberá establecer un punto de interrupción en el procedimiento de ventana de cada clase de ventana que le interese. Puede obtener la mayoría de las clases de ventana de VCL al poner su punto de interrupción condicional en Classes.StdWndProc.

Tenga en cuenta que los puntos de interrupción condicional pueden ser muy lentos. Funcionan mediante el depurador colocando allí un punto de interrupción incondicional, y cuando el SO lo desencadena, el depurador toma el control, verifica la condición y luego reanuda la ejecución si el condicional falla. Eso puede implicar una gran sobrecarga, alternar entre el depurador y su aplicación; los programas reciben lotes de mensajes, por lo que si puede encontrar una forma de evitar que el depurador interrumpa su programa para verificar cada uno de ellos, hágalo.

Si esto no es factible para lo que está tratando de depurar, entonces le recomiendo publicar una nueva pregunta donde describa el problema que realmente está tratando de resolver.

+4

Puede agregar un punto de interrupción en una dirección particular ... Ir a la ventana de puntos de interrupción después de ejecutar la aplicación se ha roto en un punto de interrupción (como en la llamada a 'GetProcAddress'), capturar la dirección del procedimiento de alguna manera, abra las ventanas de los puntos de interrupción, haga clic con el botón derecho y elija Agregar> Punto de interrupción de la dirección. Luego ingresas la dirección. El depurador debería romperse cuando llegue a esa dirección. Nota: La dirección obviamente solo es válida para una invocación de su ejecutable. – Nat

+0

+1. Esta pregunta fue motivada por un nuevo colega que es un nuevo usuario de Delphi. Echaba de menos el hecho de que en Visual Basic podía hacer una especie de "seguimiento del siguiente movimiento del usuario" (mientras se depura, el depurador se detiene al hacer clic en el usuario, ingresa, etc., pero no mientras la aplicación está "inactiva"). Usando callstack, nunca siento la necesidad de eso. Pero me di cuenta de que podía usar un BP en WindowsAPI y Mensajes para resolver algunos errores extraños.Cuando recordé que en otro depurador avanzado, podría hacer 'BPX WM_GETTEXTA' en una ventana de consola, me he preguntado si Delphi también lo hizo de una manera más fácil. – EMBarbosa

+0

@Nat hmmm ... Tal vez podría usar parte del nuevo API del Delphi Debugger para automatizar esa tarea ... Pero no estoy tan familiarizado con eso ... ¿Sería una buena pregunta? – EMBarbosa

1

Deberá acceder a Opciones | Enlazador y marque "Debug DCUs". de manera predeterminada, esto no está marcado, por lo que el depurador no pasa por todo el VCL cuando intentas trabajar.

+0

Además de esto es un comentario válido e importante. No estoy pidiendo una forma de depurar el VCL. No puedes comentar con baja reputación ... Eso no es genial. Lo sé... :( – EMBarbosa

Cuestiones relacionadas