0

我正在尝试编写一个实用方法,该方法将捕获调用它的方法的局部变量的当前值的快照(如果我理解正确,从字节码的角度来看,这些还包括方法参数) .

这是我要为每个局部变量捕获的信息:

class VariableInfo
{
    public String name;
    public String desc;
    public Object value;

    VariableInfo(String name, String desc, Object value) {
        this.name = name;
        this.desc = desc;
        this.value = value;
    }
}

我能够使用ASM...找到名称和说明(类型)

问题:我怎样才能找到局部变量的运行时当前值,例如通过它的索引?有可能做到ASM吗?还有什么办法?显然这些数据在相关的堆栈帧中更新了,但是我怎样才能访问它呢?

这是我到目前为止的一般方法:

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.objectweb.asm.tree.*;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;

public Map<String, List<VariableInfo>> recordMethodVariableValues() throws IOException {

    //TraceHelper is a utility class, to let me look one stack frame above the current one (i.e. the method that called this utility method)
    int depth = 1;
    String className = TraceHelper.getClassName(depth);
    String methodName = TraceHelper.getMethodName(depth);

    InputStream is = readClass(className);
    ClassReader reader = new ClassReader(is);

    ClassNode classNode = new ClassNode();
    reader.accept((ClassVisitor) classNode, 0);

    //Since the method may be overloaded, and I look it up by name, I may find several matching methods... is there a better way to identify only the encapsulating method?
    Map<String, List<VariableInfo>> methodInfos = new HashMap<>();
    int counter = 0;

    for (final MethodNode mn : classNode.methods) {
        if (methodName.equals(mn.name))
        {
            System.out.println("Looking up variables of method: " + mn.name);
            List<VariableInfo> variableInfos = new ArrayList<>();
            for (LocalVariableNode n : mn.localVariables)
            {
                System.out.println("Looking up value of variable: " + n.name);
                //TODO... How to find the local variable current value, e.g. by its index?
                variableInfos.add(new VariableInfo(n.name, n.desc, getLocalVariableValueByIndex(n.index)));
            }
            methodInfos.put(mn.name + "-" + ++counter, variableInfos);
        }
    }

    return methodInfos;
}
4

0 回答 0