Как найти текущие значения локальных переменных какого-то общего метода? - PullRequest
0 голосов
/ 11 февраля 2019

Я пытаюсь написать вспомогательный метод, который бы захватывал снимок текущих значений локальных переменных (если я правильно понимаю, с точки зрения байт-кода, они также включают в себя параметры метода) метода, в рамках которогоон называется.

Вот информация, которую я хочу получить для каждой локальной переменной:

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;
}
...