remote debug application java eclipse debugging jdb

java - debug - Romper cuando a una variable se le asigna algún valor



java debug remote (5)

Quiero que jdb (que estoy usando a través del depurador Eclipse) se rompa cuando a una variable se le asigna algún valor. No estoy interesado en establecer un punto de interrupción en una línea específica, sino de manera más general.

Por ejemplo, rompa cada vez x == nulo.

Es tal cosa alcanzable?


Lo sentimos, pero no hay forma de hacer lo que quieras en Eclipse. Lo que necesita es un punto de observación con la expresión condicional de un punto de interrupción. No existe en Eclipse.

Tu problema también es depuración específica de una biblioteca. Probablemente haya otras maneras de lograr lo que necesita. Busque en el foro para ver cómo lo hacen los desarrolladores.


Puede acercarse bastante con Field Modification Watchpoints . Están limitados a colocarse en campos de objetos (no variables locales, parámetros o expresiones) y se activan cada vez que se escribe el campo, pero es lo más cercano que Eclipse tiene a lo que desea.


Sí, esos se llaman puntos de observación , y los puntos de observación pueden tener expresiones de vigilancia .

Dependiendo de las versiones, haga esto seleccionando una variable en la vista de Esquema y haciendo clic derecho sobre ella, o en la vista de Variables, controle / haga clic en ella.

Un menú contextual tendrá opciones para Agregar expresión de reloj y Editar expresión de reloj .


Sí, lo que necesita configurar es un "Punto de interrupción condicional" : esto le permite detener la ejecución del programa y pasar por el depurador cuando se alcanza un determinado estado de la aplicación.

Entonces, digamos que desea saltar a un punto particular de la ejecución cuando se cumple una determinada condición (según la imagen adjunta), puede hacerlo de la siguiente manera:

  1. Abra su perspectiva del depurador y seleccione la pestaña ''BreakPoints''

  2. Agregue un nuevo BreakPoint en el archivo de código, en el lugar apropiado donde le gustaría observar la ejecución del programa

  3. A continuación, vuelva a la pestaña "Puntos de interrupción" , haga clic con el botón derecho en la entrada recién agregada y seleccione "Propiedades de punto de interrupción".

  4. Establezca la condición en la que se debe activar


Editar : El ticket que he vinculado en esta respuesta ha sido marcado verificado / corregido. Se ha integrado en la última versión de Oxygen, tal como se detalla en las notas de la versión . Dejaré mi respuesta original a continuación, ya que contiene mucha información útil sobre cómo JDI y JDT trabajan juntos en Eclipse.

Comenzaré con la respuesta final a su pregunta para que no tenga que leer los detalles si no lo desea. Básicamente, esto es posible pero con muchas preguntas que deben ser respondidas primero. Si quieres omitir eso e ir directamente al boleto, aquí tienes , pero te recomiendo que sigas leyendo.

Eclipse usa JDI (parte inferior de esa página) para registrar puntos de observación con la JVM. Esto se hace a través de los métodos EventRequestManager (la implementación es proporcionada por la propia JVM, no por Eclipse) que crea puntos de EventRequstManager.createModificationWatchpointRequest , es decir, EventRequstManager.createModificationWatchpointRequest . Lo único que estos métodos aceptan es un Field (tenga en cuenta que esta no es la clase de Field reflexivo). En resumen, Eclipse no puede hacerlo directamente a través de Java. No temas, Java tampoco maneja puntos de interrupción condicionales. Esos también se implementan a través de Eclipse directamente en lugar de depender de Java. Sin embargo, hay algunas advertencias que hacen que los puntos de observación condicionales sean mucho más difíciles de implementar que los puntos de interrupción condicionales.

Consideremos puntos de interrupción simples y condicionales. Para que funcionen, necesitas un contexto en el que puedas ejecutar el fragmento de código. Sin un contexto de ejecución para el código, no podemos evaluar la expresión / declaraciones en el fragmento porque no tenemos forma de resolver variables, valores, tipos, etc. Esto se hace usando un analizador AST que procesa el código Java en instrucciones reales . Recuerde que puede escribir un número de declaraciones en una condición, no solo una sola expresión. El evaluador luego usa un contexto (específicamente, un IJavaStackFrame ) para evaluar la expresión misma después de analizarla.

Ahora piense en un punto de observación condicional, porque ese último punto es muy importante. ¿Cuál es el contexto de ejecución de un punto de observación? El acceso variable puede ocurrir no solo dentro de la misma clase, sino también en otras clases (piense en miembros protected y miembros del paquete), y también en clases internas (a través de MyClass.this.myField ). Esto significa que:

  1. las variables locales nunca son consistentes ya que se puede acceder al campo desde múltiples métodos,
  2. las variables miembro de la clase desde la cual se invoca el acceso nunca son consistentes ya que se puede acceder al campo desde múltiples clases,
  3. las clases importadas que están disponibles en el contexto de ejecución nunca son consistentes por la misma razón que (2) y
  4. el acceso del campo en sí nunca es uniforme ya que puede requerir calificación con una instancia, nombre de clase, super o con algo como MyClass.this.myField (para el acceso de clase interna).

La viabilidad de tal característica es algo limitada. Sería muy difícil evaluar realmente un enunciado condicional no cambiante para un punto de observación ya que absolutamente nada en el contexto de ejecución va a ser consistente. Esto significa que el código no se puede analizar e interpretar fácilmente sin un significado especial aplicado a partes del código, como por ejemplo:

myField es siempre el mismo que this.myField o super.myField o MyClass.myField o MyClass.this.myField , dependiendo de dónde se accede al campo.

Esto complica bastante las cosas, especialmente en un sistema que ya es relativamente complejo. here puede encontrar un ejemplo del código de punto de interrupción condicional (busque getEvaluationEngine usando Ctrl + F). Ahora tome eso y agregue el procesamiento previo en la expresión en función de un conjunto de reglas sobre dónde estamos y dónde se encuentra el campo, y hacer las cosas puede ser complicado.

AFAIK, no puedes hacer algo como "si el valor antiguo / nuevo es esto, suspende", porque esa información simplemente no está disponible en la información que puedes obtener en el marco de la pila (y, por lo tanto, del depurador). La expresión que se asigna al valor se ha evaluado por el tiempo en que se golpea el punto de observación, pero su resultado no está disponible para el depurador, por lo tanto, no está disponible para un evaluador en el mismo punto de observación. Debería realizarse un paso primero para realizar la tarea, luego la expresión debería evaluarse después del paso. Sería horriblemente desordenado, y honestamente, bastante hacky en eso.

En cualquier caso, si desea expresar su apoyo a esta función, puede usar este ticket de Eclipse . Sin embargo, ha existido desde 2005 (8 años a partir de ahora) y tiene un apoyo limitado de la comunidad. TBH, no veo que vaya muy lejos, especialmente sin una mayor clarificación de las expectativas detrás de este tipo de solicitud de funciones y sin una importante consideración de diseño puesta en primer lugar.