[9] RFR(S): 8075214: SIGSEGV in nmethod sweeping
Mikael Gerdin
mikael.gerdin at oracle.com
Wed Mar 25 14:51:12 UTC 2015
Hi Tobias,
Handling Java-level exceptions in the C++ code is fairly convoluted.
Stare in horror at the macros in exceptions.hpp and see my comments below.
On 2015-03-25 14:53, Tobias Hartmann wrote:
> Hi,
>
> please review the following patch.
>
> https://bugs.openjdk.java.net/browse/JDK-8075214
> http://cr.openjdk.java.net/~thartmann/8075214/webrev.00/
818 Klass* k =
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true,
THREAD);
This THREAD and a lot of the following ones need to be CHECK_NULL
If any function throws a Java exception (such as OOME) then you cannot
continue and must return a failure to the caller.
I realize that at this exact point resolving the Thread class should not
fail, but if it does for some strange reason you will SEGV a few lines
below. You could make this a CATCH, which will crash the VM on an
unexpected exception, which may be ok for a white box test function.
819 instanceKlassHandle klass(THREAD, k);
820 instanceHandle thread_oop = klass->allocate_instance_handle(THREAD);
You can get OOME here and need to bail out if thread_oop is null due to
an allocation failure, change this THREAD to CHECK_NULL
821
822 Handle name = java_lang_String::create_from_str("WB Sweeper
thread", THREAD);
Allocating memory for the String can OOME, replace with CHECK_NULL
823
824 // Initialize thread_oop to put it into the system threadGroup
825 Handle thread_group(THREAD, Universe::system_thread_group());
826 JavaValue result(T_VOID);
827 JavaCalls::call_special(&result,
828 thread_oop,
829 klass,
830 vmSymbols::object_initializer_name(),
831
vmSymbols::threadgroup_string_void_signature(),
832 thread_group,
833 name,
834 THREAD);
I'd pass CHECK_NULL here as well, since it's unclear if Thread::<init>
can throw any exception.
835
836 KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass());
837 JavaCalls::call_special(&result,
838 thread_group,
839 group,
840 vmSymbols::add_method_name(),
841 vmSymbols::thread_void_signature(),
842 thread_oop, // ARG 1
843 THREAD);
Adding to the thread group can cause an OOME (the Arrays.copyOf
allocates a new array), add CHECK_NULL.
844
845 {
846 MutexLocker mu(Threads_lock);
847
848 // create sweeper thread w/ custom entry -- one iteration
instead of loop
849 CodeCacheSweeperThread* sweeper_thread = new
CodeCacheSweeperThread();
850 sweeper_thread->set_entry_point(&WhiteBox::sweeper_thread_entry);
851
852 // check that thread and osthread were created
853 if (sweeper_thread == NULL || sweeper_thread->osthread() ==
NULL) {
854 vm_exit_during_initialization("java.lang.OutOfMemoryError",
855
os::native_thread_creation_failed_msg());
This should be vm_exit_out_of_memory, not "during initialization".
856 }
857
/Mikael
>
> Problem:
> The test uses the Whitebox API to enforce sweeping by creating and starting a 'CodeCacheSweeperThread'. During creation of the thread, the interpreter crashes in j.l.ThreadGroup.add(Thread t) [1] while executing a subtype check to validate that 't' is a subtype of j.l.Thread [2]. The problem is that we pass 'JavaThread->threadObj()' to 'ThreadGroup.add' which is invalid due to a GC that moved the object. The GC does not know about the thread because it was not yet added to the threads list and therefore does not update the oop.
>
> Solution:
> Instead of calling 'JavaThread::allocate_threadObj', the initialization is moved to the caller to make sure that setting the thread oop is done together with adding the thread to the threads list. I also fixed the missing oom handling described as one of the problems in JDK-8072377 [3].
>
> Testing:
> - 1k runs of failing testcase
> - JPRT
>
> Thanks,
> Tobias
>
> [1] http://hg.openjdk.java.net/jdk9/hs-comp/jdk/file/tip/src/java.base/share/classes/java/lang/ThreadGroup.java#l896
> [2] see '__ gen_subtype_check' in 'TemplateTable::aastore'
> [3] https://bugs.openjdk.java.net/browse/JDK-8072377
>
More information about the hotspot-compiler-dev
mailing list