Discussing some related changes with Alan Bateman, it was observed that GetThreadGroupChildren has code to skip over hidden threads:
for (int i=0, j=0; i<nthreads; i++) {
oop thread_obj = threads->obj_at(i);
assert(thread_obj != NULL, "thread_obj is NULL");
JavaThread *javathread = java_lang_Thread::thread(thread_obj);
// Filter out hidden java threads.
if (javathread != NULL && javathread->is_hidden_from_external_view()) {
hidden_threads++;
continue;
}
thread_objs[j++] = Handle(current_thread, thread_obj);
}
but this code is traversing the members of a ThreadGroup and there should not be any hidden threads in any ThreadGroup - if there were then it would be strange to filter them via JVMTI but not via direct use of ThreadGroup.enumerate().
This day-one code seems to be based on a copy-n-paste from GetAllThreads, which traverses the Threads_list and so can encounter hidden threads.
for (int i=0, j=0; i<nthreads; i++) {
oop thread_obj = threads->obj_at(i);
assert(thread_obj != NULL, "thread_obj is NULL");
JavaThread *javathread = java_lang_Thread::thread(thread_obj);
// Filter out hidden java threads.
if (javathread != NULL && javathread->is_hidden_from_external_view()) {
hidden_threads++;
continue;
}
thread_objs[j++] = Handle(current_thread, thread_obj);
}
but this code is traversing the members of a ThreadGroup and there should not be any hidden threads in any ThreadGroup - if there were then it would be strange to filter them via JVMTI but not via direct use of ThreadGroup.enumerate().
This day-one code seems to be based on a copy-n-paste from GetAllThreads, which traverses the Threads_list and so can encounter hidden threads.