如何在jvmti中唯一标识线程

时间:2015-09-22 13:12:30

标签: java multithreading agent jvmti

我正在研究JVMTI代理,我想在方法上输入和退出时识别相同的线程。我能够获得线程名称,但这还不够。

想象一下,你有一个像这样的方法:

public class Main {
    public static void myMethod() {
        System.out.println("doing something as " + Thread.currentThread().getName());
        Thread.currentThread().setName("SomethingDifferent");
        System.out.println("doing something as same thread " + Thread.currentThread().getName());
    }
}

因此,输入此方法将有一个名称,退出此主题的名称也不同。

当像这样使用JVMTI时:

static void JNICALL callback_on_method_entry(jvmtiEnv *jvmti, JNIEnv* env,
    jthread thread, jmethodID method)
{
    ...
    (*jvmti)->GetThreadInfo(jvmti, thread, &info);
    ...
}

static void JNICALL callback_on_method_exit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jmethodID method, jboolean was_popped_by_exception, jvalue return_value)
{
    ...
    (*jvmti)->GetThreadInfo(jvmti, thread, &info);
    ...
}

每个info将报告不同的线程名称,我希望它们具有相同的标识符。

如何获得该线程的相同标识符?

一种解决方案可以是获取引用的Threadtid)的字段值。 怎么做 ?我可以通过堆迭代但​​我无法获得字段名称。

2 个答案:

答案 0 :(得分:1)

正如您所指出的,一种解决方案是使用GetFieldName。这需要你查找jfieldid,这真的很烦人。

我看到其他人这样做的方式是简单地分配他们自己的ID并将其存储在线程本地存储中。请参阅UofO的TAU项目中的JavaThreadLayer.cpp,特别是JavaThreadLayer::GetThreadId()函数。

答案 1 :(得分:1)

我终于找到了另一个简单的方法:

因为进入/退出回调在同一个线程中运行,所以可以使用pthread_self()并将其转换为例如到unsigned int。它与您在java中找到的tid不一样,但是虽然名称发生了变化,但您将获得线程的唯一编号。