Инструментарий байт-кода ASM для входа/выхода метода
-
13-09-2019 - |
Вопрос
Я создал агент JVMTI, который на высоком уровне выполняет следующие действия:
onClassLoadHook отправляет байт-коды загруженного класса в отдельный процесс Java, который будет инструментировать класс с помощью ASM.
верните байт-коды и загрузите их
В моем отдельном Java-процессе, который обрабатывает загруженный класс Java, я делаю следующее:
.. ..
cr = new ClassReader(inBytes, offset, inLen);
cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassAdapter ca = new ClassAdapter(cw) {
..
..
@Override
public MethodVisitor visitMethod(final int access,
final String name,
final String desc,
String signature,
String[] exceptions) {
return new MethodAdapter(mv) {
@Override
public void visitCode() {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/amir/Tester", "callTestStatic3", "(Ljava/lang/Object;)V");
mv.visitCode();
}
}
}
Когда я пытаюсь декомпилировать класс, написанный после этого инструментария, с помощью Java Decompiler, я вижу следующую декомпилированную функцию, которая, как я знаю, неверна:
public void func1(int arg1, int arg2)
{
int b;
Tester.callTestStatic3(???);
System.out.println("arg = " + a + " b = " + b);
}
потому что моя функция на самом деле выглядит так:
public void func1(int a, int b)
{
System.out.println("arg = " +a + " b = " +b);
}
Может ли кто-нибудь сказать мне, сделал ли я здесь что-то не так?Моя единственная подсказка заключается в том, что если вместо того, чтобы передавать в качестве аргумента моей функции указатель THIS, если я передаю примитивные типы, все работает отлично.Есть ли что-то особенное в указателе THIS, которым мне нужно управлять?Я сравнил байт-коды и использовал ASMIFIER, чтобы понять, какие операторы мне нужно использовать для генерации правильных байт-кодов.
Решение
Похоже, ваш код правильный, с mv.visitCode().javap показывает ожидаемые байт-коды.Я думаю, ваш первоначальный декомпилятор просто поступал неправильно.
Другие советы
Возможно, это не имеет значения, но разве тебе не следует звонить super.visitCode()
?
@Override
public void visitCode() {
super.visitCode();
...
я бы использовал ТрассКлассПосетитель чтобы проверить, что именно генерируется.