[9] RFR(S): 8075214: SIGSEGV in nmethod sweeping
Tobias Hartmann
tobias.hartmann at oracle.com
Thu Mar 26 08:49:51 UTC 2015
Hi,
Mikael, thanks a lot for the detailed explanation. I was not aware of these macros.
I agree with David that this code is buggy and as Vladimir suggested, I will investigate if we can request the sweeping from the existing sweeper thread without creating a new one. We already have the functionality to notify the sweeper but need some further synchronization to block until a full sweep is done.
Thanks,
Tobias
On 25.03.2015 15:51, Mikael Gerdin wrote:
> 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