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

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

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

Достижима ли такая вещь?

Ответ 1

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

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

  • Откройте перспективу отладчика и выберите вкладку "Брейкпойнты

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

  • Затем вернитесь на вкладку "Точки останова" , щелкните правой кнопкой мыши на новой добавленной записи и выберите "Свойства точки останова"

  • Задайте условие, на котором оно должно быть активировано

alt text

Ответ 2

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

Ответ 3

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

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

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

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

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

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

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

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

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

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

Ответ 4

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

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

В контекстном меню будут выделены опции Add Watch Expression и Edit Watch Expression.

Ответ 5

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

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