Así que quiero poner un punto de interrupción en una API específica o un mensaje de Windows. No encuentro ninguna manera fácil de hacerlo sin escribir código en ninguna versión Delphi. ¿Hay alguna manera de hacerlo de forma similar a como puedo poner un punto de interrupción en el acceso a la memoria?¿Hay alguna manera rápida de, al depurar, detenerse en un mensaje o API específico de Windows?
Respuesta
Para detener en cualquier llamada a una función API, lo encuentran en la sección de implementation
windows.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.
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.
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
- 1. ¿Hay alguna manera de depurar un subproceso utilizando pydev?
- 2. ¿Existe alguna manera rápida de eliminar un valor específico de una matriz en Javascript?
- 3. ¿Hay alguna manera de deshabilitar ReSharper para un archivo específico?
- 4. ¿Hay alguna manera rápida de crear un conjunto?
- 5. ¿Cómo puedo (¿hay alguna manera de) convertir un HRESULT en un mensaje de error específico del sistema?
- 6. ¿Hay alguna manera de depurar aplicaciones web usando Eclipse?
- 7. ¿Hay alguna manera de insertar a través de Graph API?
- 8. ¿Hay alguna API Win32 para activar el modo de hibernación o suspensión en Windows?
- 9. ¿Hay alguna manera de procesar SVG en Windows Forms?
- 10. Al depurar javascript, ¿hay alguna manera de alertar la pila de llamadas actual?
- 11. ¿Hay alguna manera de detectar el estado del monitor en Windows (encendido o apagado)?
- 12. ¿Hay alguna manera de usar fopen_s() con GCC o al menos crear un #define al respecto?
- 13. ¿Hay una mejor manera de depurar SQL?
- 14. ¿Hay alguna manera de memorizar o materializar un IEnumerable?
- 15. ¿Hay alguna manera de verificar el historial de trabajo registrado por un usuario específico en JIRA?
- 16. ¿Hay alguna manera de ingresar automáticamente al ejecutar un shell?
- 17. ¿Hay alguna manera de detener el tiempo. ¿Duerme en Windows?
- 18. ¿Hay alguna manera de dar un nombre de archivo específico al guardar un archivo mediante curl en Mac OS X?
- 19. ¿Hay alguna manera de imitar o en genéricos de Java
- 20. ¿Hay alguna manera de vincular un párrafo específico en una página sin anclas?
- 21. ¿Hay alguna manera de ejecutar las pruebas NUnit en un pedido específico?
- 22. estado de git: ¿hay alguna manera de mostrar los cambios solo en un directorio específico?
- 23. ¿Hay alguna manera de depurar plantillas de Velocity en el sentido tradicional de depuración de código?
- 24. ¿Hay alguna manera de ofuscar las claves de API en un paquete R?
- 25. ¿hay alguna manera de usar tr /// (o equivalente) en java?
- 26. ¿Hay alguna manera de acceder al hardware directamente en Python?
- 27. ¿Hay alguna manera de usar Canvas en IE7 o IE8?
- 28. ¿Hay alguna manera de cambiar el propietario de un JDialog?
- 29. manera más rápida de llegar a la media de un campo específico en MongoDB
- 30. ¿Hay alguna manera de no enviar un formulario web completo al hacer clic en un botón?
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
+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
@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