it-roy-ru.com

Разрыв, когда переменной присваивается какое-то значение

Я хочу, чтобы jdb (который я использую через отладчик Eclipse) ломался, когда переменной присваивалось какое-то значение .. Меня не интересует установка точки останова в какой-то конкретной строке, а скорее в более общем смысле. 

Например, разрывать каждый раз, когда x == ноль.

Это достижимо?

35
Daniel

Да - вам нужно установить «Условную точку останова» - это дает вам возможность остановить выполнение программы и пройти через отладчик, когда достигается определенное состояние приложения.

Итак, допустим, что вы хотите перейти к определенной точке выполнения при выполнении определенного условия (согласно приложенному изображению), вы можете сделать это следующим образом:

  1. Откройте перспективу отладчика и выберите вкладку «BreakPoints»  

  2. Добавьте новую точку останова в файле кода - в соответствующем месте, где вы хотели бы наблюдать за выполнением программы

  3. Затем вернитесь на вкладку «Точки останова» , щелкните правой кнопкой мыши вновь добавленную запись и выберите «Свойства точки останова»

  4. Установите условие, при котором он должен быть активирован

alt text

32
Dinuk

Edit: Билет, который я связал в этом ответе был помечен как проверенный/исправленный. Он был интегрирован в последнюю версию Oxygen, как описано в примечаниях к выпуску . Я оставлю свой оригинальный ответ ниже, поскольку в нем содержится много полезной информации о том, как JDI и JDT работают вместе в Eclipse.


Я собираюсь начать с окончательного ответа на ваш вопрос, поэтому вам не нужно читать подробности, если вы не хотите. В принципе, это возможно, но с большим количеством вопросов, на которые нужно ответить в первую очередь. Если вы хотите пропустить это и перейти прямо к билету, здесь вы идете , но я рекомендую вам читать дальше.

Eclipse использует JDI (в самом низу этой страницы) для регистрации точек наблюдения в JVM. Это делается с помощью методов EventRequestManager (реализация обеспечивается самой JVM, а не Eclipse), которые создают точки наблюдения, т.е. EventRequstManager.createModificationWatchpointRequest . Единственное, что принимают эти методы, это Field (обратите внимание, что это не отражающий класс Field ). Короче говоря, Eclipse не может сделать это напрямую через Java. Не бойтесь, Java также не обрабатывает условные точки останова. Они также реализуются через Eclipse напрямую, вместо того, чтобы полагаться на Java. Однако есть некоторые оговорки, которые делают условные контрольные точки гораздо более сложными для реализации, чем условные контрольные точки.

Давайте рассмотрим простые, условные точки останова. Чтобы они работали, вам нужен контекст, в котором вы можете выполнить фрагмент кода. Без контекста выполнения для кода мы не сможем оценить выражение/операторы во фрагменте, поскольку у нас нет способа разрешения переменных, значений, типов и т.д. Это делается с помощью AST parser, который обрабатывает код Java в реальных инструкциях. Помните, что в условие можно ввести несколько операторов, а не одно выражение. Затем оценщик использует контекст (в частности, IJavaStackFrame ) для оценки самого выражения после его синтаксического анализа.

Теперь подумайте об условной точке наблюдения, потому что последняя точка очень важна. Что такое контекст выполнения точки наблюдения? Доступ к переменным может происходить не только в пределах одного и того же класса, но и в других классах (например, protected и члены пакета), а также во внутренних классах (через MyClass.this.myField). Это означает, что:

  1. локальные переменные никогда не бывают непротиворечивыми, так как к полю можно получить доступ несколькими способами,
  2. переменные-члены класса, из которого вызывается доступ, никогда не являются согласованными, поскольку к полю можно получить доступ из нескольких классов,
  3. импортированные классы, доступные в контексте выполнения, никогда не согласуются по той же причине, что и (2), и
  4. доступ к самому полю никогда не бывает согласованным, поскольку может потребоваться квалификация с экземпляром, именем класса, super или чем-то вроде MyClass.this.myField (для доступа к внутреннему классу).

Возможность реализации такой функции ограничена. Вам было бы трудно реально оценить неизменяемый условный оператор для точки наблюдения, поскольку абсолютно ничего в контексте выполнения не будет согласованным. Это означает, что код не может быть легко проанализирован и интерпретирован без специального значения, примененного к частям кода, таким как:

myField всегда совпадает с this.myField или super.myField или MyClass.myField или MyClass.this.myField, в зависимости от того, где осуществляется доступ к полю.

Это немного усложняет ситуацию, особенно в системе, которая уже является относительно сложной. Пример условного кода точки останова можно найти здесь (поиск getEvaluationEngine, используя Ctrl + F). Теперь возьмите это и добавьте предварительную обработку выражения, основанного на наборе правил о том, где мы находимся и где находится поле, и выполнение каких-либо задач может стать сложным.

AFAIK, вы не можете сделать что-то вроде «если старое/новое значение - это, приостановить», потому что эта информация просто недоступна из информации, которую вы можете получить в кадре стека (и, следовательно, из отладчика). Выражение, присваиваемое значению, было оценено по времени попадания в точку наблюдения, но его результат недоступен отладчику, поэтому он не доступен для оценщика на самой точке наблюдения. Сначала должен быть выполнен шаг для выполнения присваивания, затем выражение должно быть оценено после шага. Это было бы ужасно грязно и, честно говоря, довольно глупо.

В любом случае, если вы хотите выразить свою поддержку этой функции, вы можете использовать этот билет Eclipse . Тем не менее, он существует с 2005 года (8 лет на данный момент) и имеет ограниченную поддержку со стороны сообщества. TBH, я не вижу, чтобы это зашло слишком далеко, особенно без дополнительного разъяснения ожиданий, связанных с такого рода запросом функции, и без какого-либо серьезного конструктивного рассмотрения, поставленного вначале.

9
Brian

Вы можете подойти довольно близко с Field Watch Modification Watchpoints . Они ограничены размещением в полях объектов (не локальных переменных, параметров или выражений), и они запускаются всякий раз, когда в поле записывается, но Eclipse ближе всего к тому, что вы хотите. 

9
Old Pro

Да, они называются точки наблюдения , и точки наблюдения могут иметь смотреть выражения .

В зависимости от версий и т.д. Вы делаете это, выбирая переменную в представлении Outline и щелкая правой кнопкой мыши по ней или в представлении Variables, контролируя/щелкая по ней. 

В контекстном меню можно выбрать Добавить выражение просмотра и Редактировать выражение просмотра .

5
DigitalRoss

Извините, но в Eclipse нет способа делать то, что вы хотите. То, что вам нужно, это точки наблюдения с условным выражением точки останова. Он не существует в Eclipse.

Ваша проблема также в конкретной отладке библиотеки. Возможно, есть и другие способы достичь того, что вам нужно. Поиск по форуму, чтобы увидеть, как разработчики делают это.

0
mki