如何使用 ASM 获取在另一个线程中执行的代码?

How get code which executes in another thread with ASM?

我需要帮助。例如我有这样的 class.

public class ThreadTest {
    public void runThreads() {
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int i = 1;
            System.out.println("Thread " + i);
        });

        Thread t2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int i = 2;
            System.out.println("Thread " + i);
        });
        t1.start();
        t2.start();
    }
}

我 运行 classThreadTest 的访客。我想获取在第一个和第二个线程中执行的字节码。有什么办法吗?我想我应该访问class Thread然后访问其中的方法run。但是我怎样才能从 ThreadTest 做到这一点?

您必须了解 how lambdas are compiled. There is no point in analyzing the code of class java.lang.Thread as its documentation 已经告诉您它将做什么,即它将调用提供的 Runnable 实例的 run 方法,但该实例将被创建在运行时由 LambdaMetaFactory.

但是您的 class ThreadTest 包含最终将被调用的实际代码。它位于 class 中的合成方法中。当你遍历runThreads()方法时你会encounter invokedynamic instructions. The bsmArgs parameter depends on the actual bootstrap method of the invokedynamic instruction, so you have to look up its documentation理解它的含义。您将了解到它包含一个指向(合成)目标方法(在您的 class 中)的句柄。所以你知道 那个方法 包含最终将由另一个线程执行的代码。

在您的情况下,您会遇到两条 invokedynamic 指令,它们指向不同的合成方法,代表不同线程执行的不同代码。