We output info about Thread-SMR during an error report.
Normally Thread-SMR output is generated while the Threads_lock
is held so the info is stable. However, during error reporting
grabbing the Threads_lock is deadlock prone so we skip it. Of
course, this means that we're racy during error reporting.
Robbin reported this via email:
Hi Dan,
I sometimes see this, it seem like Threads::print_on_error uses a freed list. I think a thread removes itself exactly the same time as we get a signal and start doing error reporting.
/Robbin
==8527== Thread 79:
==8527== Invalid read of size 4
==8527== at 0x52071BB: ThreadsList::length() const (threadSMR.hpp:173)
==8527== by 0x6424C9E: ThreadsSMRSupport::print_info_elements_on(outputStream*, ThreadsList*) (threadSMR.cpp:1059)
==8527== by 0x64248E2: ThreadsSMRSupport::print_info_on(outputStream*) (threadSMR.cpp:1002)
==8527== by 0x641AEEA: Threads::print_on_error(outputStream*, Thread*, char*, int) (thread.cpp:4685)
==8527== by 0x64AA164: VMError::report(outputStream*, bool) (vmError.cpp:807)
==8527== by 0x64ABB35: VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long) (vmError.cpp:1394)
==8527== by 0x64AB4DC: VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*) (vmError.cpp:1239)
==8527== by 0x59F6B37: report_vm_error(char const*, int, char const*, char const*, ...) (debug.cpp:214)
==8527== by 0x5B3F866: Thread::stack_base() const (thread.hpp:615)
==8527== by 0x64A9838: VMError::report(outputStream*, bool) (vmError.cpp:672)
==8527== by 0x64ABB35: VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long) (vmError.cpp:1394)
==8527== by 0x64AB4DC: VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*) (vmError.cpp:1239)
==8527== Address 0x3ed84da8 is 40 bytes inside a block of size 80 free'd
==8527== at 0x4C2FD18: free (vg_replace_malloc.c:530)
==8527== by 0x61F5DC3: os::free(void*) (os.cpp:777)
==8527== by 0x5206D42: FreeHeap(void*) (allocation.inline.hpp:89)
==8527== by 0x620F85A: CHeapObj<(MemoryType)2>::operator delete(void*) (allocation.inline.hpp:142)
==8527== by 0x6423CA9: ThreadsSMRSupport::free_list(ThreadsList*) (threadSMR.cpp:732)
==8527== by 0x6424452: ThreadsSMRSupport::remove_thread(JavaThread*) (threadSMR.cpp:893)
==8527== by 0x6419BBC: Threads::remove(JavaThread*) (thread.cpp:4391)
==8527== by 0x52152A2: SingleTestThread<void (*)(Thread*)>::postrun() (test_concurrentHashtable.cpp:61)
==8527== by 0x5214E0E: SingleTestThread<void (*)(Thread*)>::run() (test_concurrentHashtable.cpp:57)
==8527== by 0x61FEF79: thread_native_entry(Thread*) (os_linux.cpp:707)
==8527== by 0x8C6536C: start_thread (in /usr/lib64/libpthread-2.25.so)
==8527== by 0x8799B9E: clone (in /usr/lib64/libc-2.25.so)
==8527== Block was alloc'd at
==8527== at 0x4C2EB6B: malloc (vg_replace_malloc.c:299)
==8527== by 0x61F58AC: os::malloc(unsigned long, MemoryType, NativeCallStack const&) (os.cpp:676)
==8527== by 0x5206C83: AllocateHeap(unsigned long, MemoryType, NativeCallStack const&, AllocFailStrategy::AllocFailEnum) (allocation.inline.hpp:58)
==8527== by 0x620F9FB: CHeapObj<(MemoryType)2>::operator new(unsigned long, NativeCallStack const&) (allocation.inline.hpp:95)
==8527== by 0x620F751: CHeapObj<(MemoryType)2>::operator new(unsigned long) (allocation.inline.hpp:103)
==8527== by 0x6422CB4: ThreadsList::add_thread(ThreadsList*, JavaThread*) (threadSMR.cpp:394)
==8527== by 0x642398E: ThreadsSMRSupport::add_thread(JavaThread*) (threadSMR.cpp:655)
==8527== by 0x6419AD1: Threads::add(JavaThread*, bool) (thread.cpp:4373)
==8527== by 0x5215259: SingleTestThread<void (*)(Thread*)>::prerun() (test_concurrentHashtable.cpp:50)
==8527== by 0x5214DEE: SingleTestThread<void (*)(Thread*)>::run() (test_concurrentHashtable.cpp:55)
==8527== by 0x61FEF79: thread_native_entry(Thread*) (os_linux.cpp:707)
==8527== by 0x8C6536C: start_thread (in /usr/lib64/libpthread-2.25.so)