Pergunta

Eu criei um agente JVMTI que faz o seguinte a um nível elevado:

  • onClassLoadHook enviar os bytecodes para a classe carregada a um processo Java separado que instrumento a classe usando ASM

  • obter os bytecodes para trás e carregá-los

No meu processo de java separado que os instrumentos a carregado de classe Java que eu faça o seguinte:

.. ..

    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();

                }

            }
        }

Quando tento decompile a classe que está escrito após essa instrumentação usando Java Decompiler - Eu vejo o seguinte função descompilados que eu sei que está errado:

  public void func1(int arg1, int arg2)
  {
    int b;
    Tester.callTestStatic3(???); 
    System.out.println("arg = " + a + " b = " + b);

  }

porque minha função realmente se parece com isso:

public void func1(int a, int b) 
{

    System.out.println("arg = " +a + " b = " +b);

}

Alguém pode me dizer se eu fiz algo errado aqui? Minha única pista é que, se em vez de passar como um argumento para a minha função a este ponteiro, se eu passar em tipos primitivos, tudo funciona finie. Há algo especial sobre o este ponteiro que eu preciso para gerenciar? Eu comparei os bytecodes, e eu usei ASMIFIER para obter uma pista sobre o que declarações que eu preciso usar para gerar o bytecode certas.

Foi útil?

Solução

Parece que o seu código está correto, com mv.visitCode (). javap mostra os Bytecodes esperados. Eu acho que o seu decompiler originais simplesmente não estava fazendo a coisa certa.

Outras dicas

Talvez não importa, mas você não deveria estar chamando super.visitCode()?

@Override
public void visitCode() {
  super.visitCode();
  ...

Eu usaria TraceClassVisitor para verificar exatamente o que estava sendo gerado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top