jvmti中如何唯一标识线程
How to uniquely identify thread in 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
将报告不同的线程名称,我希望它们具有相同的标识符。
如何为线程获取相同的标识符?
一种解决方案是获取引用的 Thread
(tid
) 的字段值。
怎么做 ?我可以遍历堆,但我无法获取字段名称。
正如您所指出的,一种解决方案是使用 GetFieldName。这需要您查找 jfieldid,这真的很烦人。
我见过其他人这样做的方式是简单地分配他们自己的 ID 并将其存储在线程本地存储中。请参阅 UofO 的 TAU 项目中的 JavaThreadLayer.cpp,特别是 JavaThreadLayer::GetThreadId()
函数。
我终于找到了另一个简单的解决方案:
因为 entry/exit 回调在同一个线程中 运行,所以可以使用 pthread_self()
并进行转换,例如至 unsigned int
。它与您在 java 中找到的 tid
不同,但您将获得线程的唯一编号,尽管名称已更改。
我正在研究 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
将报告不同的线程名称,我希望它们具有相同的标识符。
如何为线程获取相同的标识符?
一种解决方案是获取引用的 Thread
(tid
) 的字段值。
怎么做 ?我可以遍历堆,但我无法获取字段名称。
正如您所指出的,一种解决方案是使用 GetFieldName。这需要您查找 jfieldid,这真的很烦人。
我见过其他人这样做的方式是简单地分配他们自己的 ID 并将其存储在线程本地存储中。请参阅 UofO 的 TAU 项目中的 JavaThreadLayer.cpp,特别是 JavaThreadLayer::GetThreadId()
函数。
我终于找到了另一个简单的解决方案:
因为 entry/exit 回调在同一个线程中 运行,所以可以使用 pthread_self()
并进行转换,例如至 unsigned int
。它与您在 java 中找到的 tid
不同,但您将获得线程的唯一编号,尽管名称已更改。