Автономный верификатор байт-кода

В моем проекте инструментирования байт-кода я часто натыкаюсь на VerifyErrors. Однако java Verifier по умолчанию дает мало информации о том, какая инструкция привела к ошибке (он дает только метод и небольшое сообщение). Есть ли какой-нибудь автономный верификатор байт-кода, который предоставляет немного более продвинутую помощь в обнаружении ошибки, по крайней мере, точное местоположение инструкции? Спасибо.


person H-H    schedule 26.02.2010    source источник


Ответы (3)


Как и в любом проекте, использующем байт-код JVM, я бы сначала проверил, есть ли в BCEL что-нибудь, что может быть полезным для вас. Кроме того, возможно, FindBugs может помочь, хотя я не уверен, предполагает ли он проверяемый байт-код для начала или нет. .

person Greg Hewgill    schedule 26.02.2010
comment
Почему я не подумал об этом. На самом деле я использую BCEL, но мне никогда не приходило в голову проверить его верификатор. На самом деле у него есть один, который называется JustIce. - person H-H; 26.02.2010

ASM CheckClassAdaptor.verify() дает отличную обратную связь: http://asm.ow2.org/

person Jevgeni Kabanov    schedule 15.03.2010

Я также искал что-то, что сообщало бы о потенциальных ошибках проверки, но особенно IncompatibleClassChangeErrors. Я написал небольшой тестовый проект с одним классом API и другим клиентским классом, вызывающим методы API, а также с основным классом для запуска верификатора; затем изменили API, перекомпилировав его, но не клиент, и проверили, что можно поймать. Использовал -target 7, хотя пока никаких специальных функций JDK 7 нет.

Во-первых, и это наиболее очевидно, Class.forName может найти определенные ошибки в сигнатуре клиентского класса, но, похоже, он не проверяет тела методов на наличие вызовов несуществующих методов API и т.п., даже если вы вызываете getDeclaredMethods; об ошибках сообщает виртуальная машина только тогда, когда проблемная строка кода действительно выполняется.

JustIce в BCEL 5.2 кажется самым простым;

org.apache.bcel.verifier.Verifier.main(new String[] {clazz});

делает работу:

Pass 3a, method number 1 ['public void m()']:
VERIFIED_REJECTED
Instruction invokestatic[184](3) 4 constraint violated:
  Referenced method 'x' with expected signature '()V' not found in class 'API'.
  ....

Я пробовал ASM 4.0, но

org.objectweb.asm.util.CheckClassAdapter.main(new String[] {clazz});

не работает; возможно, он проверяет формат методов, но не компоновку. Встраивание main и передача checkDataFlow=true не помогают.

При поиске я также нашел https://kenai.com/hg/maxine~maxine/file/8429d3ebc036/com.oracle.max.vm/test/test/com/sun/max/vm/verifier/CommandLineVerifier.java, но я не смог найти способ заставить это работать; сопутствующий модульный тест выдает ClassNotFoundException при запуске.

person Jesse Glick    schedule 08.02.2012