Instrumentation de code intermédiaire générant une erreur de vérificateur Java
-
05-07-2019 - |
Question
J'utilise ASM afin de faire de l'instrumentation en bytecode pour les programmes Java. Ce que je fais est simple: lors de l’instrumentation d’une méthode, si l’instruction est un PUTFIELD, effectuez simplement un DUP_X1 juste avant l’instruction, puis visitez PUTFIELD et injectez un appel de fonction avec un argument incluant l’entrée de pile DUP.
public void visitFieldInsn(
int opcode,
String owner, // owner of this field...
String name,
String desc) {
boolean did_dup = false;
if(opcode == Opcodes.PUTFIELD) {
if(!owner.equals("java/lang/System")) {
if (desc.startsWith("L")) {
mv.visitInsn(Opcodes.DUP_X1);
did_dup = true;
}
}
}
mv.visitFieldInsn(opcode, owner, name, desc);
if (did_dup) {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/amir/ASide", "updateG", "(Ljava/lang/Object;Ljava/lang/Object;)V");
}
}
Le code ressemble à ceci AVANT et APRÈS l'instrumentation, respectivement:
public void setA(ClassA classa)
{
refA = classa;
eyeColor = classa.eyeColor;
}
public void setA(ClassA classa)
{
ASide.updateG(refA = classa, this);
ASide.updateG(eyeColor = classa.eyeColor, this);
}
Mais lorsque je lance le code instrumenté, je reçois:
java.lang.VerifyError: attente d'un objet / tableau sur la pile
Pouvez-vous proposer une aide à cet égard?
La solution
Il y a des trous dans votre instrumentation. Par exemple, il ne vérifie pas si vous êtes dans la méthode statique, donc cette variable est présente.