java - 如何使用 ObjectWeb ASM 检查字节码操作 PUTFIELD 正在重新分配属于 'this' 对象的字段?

标签 java static-analysis bytecode bytecode-manipulation java-bytecode-asm

我正在使用 ASM字节码操作框架,用于对 Java 代码执行静态分析。我希望检测何时重新分配对象的字段,即何时发生这种代码:

class MyObject {
    private int value;
    void setValue(int newValue) { this.value = newValue; }
}

使用下面的代码(在实现ClassVisitor的类中)可以检测到上述情况:

@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
    if(opcode == Opcodes.PUTFIELD) {
        // do whatever here
    }
}

但是,无论拥有该字段的对象如何,都会调用此代码。我想找到在 this 对象上执行 PUTFIELD 操作的更具体的情况。例如,我想区分第一个代码片段和如下代码:

public MyObject createNewObjectWithDifferentField() {
    MyObject newObject = new MyObject();
    newObject.value = 43;
    return newObject;
}

在上面的例子中,PUTFIELD 操作仍然被执行,但这里它是在局部变量 (newObject) 而不是 this 对象上执行的。这将取决于分配时堆栈的状态,但我遇到了几个字节码完全不同的不同场景,我正在寻找处理这种复杂性的方法。

如何检查 PUTFIELD 是否正在重新分配属于 this 对象的字段?


编辑

我使用 ASM 仅执行分析,而不是检测现有字节码。如果可能的话,我最好找到一种无需更改字节码即可发现这一点的方法。

最佳答案

我认为一般情况下是不可能的。考虑:

class MyObject {
  private int value;
  void mymethod1() {
    mymethod2(Math.random() > 0.5 ? this : new MyObject());
  }

  void mymethod2(MyObject that) {
    that.value = 1;
  }
}

在更简单的情况下,您可以将堆栈跟踪回 ALOAD 0,它在实例方法中引用 this

关于java - 如何使用 ObjectWeb ASM 检查字节码操作 PUTFIELD 正在重新分配属于 'this' 对象的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3591415/

相关文章:

Java字节码最终字段赋值(jasmin)

java - 我的浏览器中显示的可分页数据错误

java - 适用于 BlackBerry 的 LDAP 库不错吗?

oop - 为什么静态解析虚拟方法调用如此困难?

javascript - 数据属性中的 ES6 连接

java - JVM 中的非法操作码

Java Web 应用程序 sql 结果与对象列表

java - 在 switch 语句中使用 Math.signum(x) 还是 Integer.compare(x, 0) 更好?

java - 哪种静态分析工具用于扫描从一种方法到另一种方法的数据流?

java - 列出从一个方法中调用的所有未实现的方法