Преобразование ASM для поиска конкретного типа класса

Я работаю над проектом, который будет отслеживать вызовы методов из класса внутри пакета в любой другой класс. Важно, чтобы я мог идентифицировать конкретные типы, и я бы предпочел иметь минимальные накладные расходы на трассировку. Нет ограничений на время срабатывания зонда; это может быть до или после вызова метода.

В настоящее время используется ASM, но это не требуется. Система переходит от AspectJ, чтобы разрешить динамическое присоединение, так что это исключено.

Ниже представлена ​​текущая ситуация. Перечисление/синглтон Tracer получает probe(int) и обрабатывает вызов. Достаточно найти обращения от конкретных типов к ссылочным типам.

@Override
void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
    Integer probeID = Tracer.INSTANCE.probes.createProbeIDAt(new Call(owner, name, desc))

    super.visitFieldInsn(GETSTATIC, "org/flightofstairs/honours/capture/agent/Tracer", "INSTANCE", "Lorg/flightofstairs/honours/capture/agent/Tracer;");
    super.visitLdcInsn(probeID)
    super.visitMethodInsn(INVOKEVIRTUAL, "org/flightofstairs/honours/capture/agent/Tracer", "probe", "(Ljava/lang/Integer;)V")

    super.visitMethodInsn(opcode, owner, name, desc);
}

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

Было бы несложно вычислить позицию ссылки на объект в стеке, учитывая, что количество параметров известно, но java не предлагает возможности дублировать ссылку из более низкого уровня в стеке.

Любой совет?

Ваше здоровье.


person FlightOfStairs    schedule 24.05.2012    source источник


Ответы (1)


Решение состоит в том, чтобы записывать INVOKEINTERFACE во время обхода. В конце концов, ASMs Analyzer можно использовать для поиска инструкций, которые помещают объектную ссылку в стек, и оттуда легко добавить getClass() и код трассировки.

Здесь показано решение. https://gist.github.com/2795738

person FlightOfStairs    schedule 27.05.2012