RFR: 8274794: Print all owned locks in hs_err file [v2]

Thomas Stuefe stuefe at openjdk.java.net
Sat Oct 16 07:48:52 UTC 2021


On Fri, 15 Oct 2021 16:47:30 GMT, Coleen Phillimore <coleenp at openjdk.org> wrote:

>> See CR for details.  This saves the created mutex in a mutex_array during Mutex construction so that all Mutex, not just the ones in mutexLocker.cpp can be printed in the hs_err file.  ThreadCritical is used to protect the mutex_array, and to avoid UB should be used when printing the owned locks, but since that is done during error handling, this seemed better not to lock during error handling.  There's 0 probability that another thread will be creating a lock during this error handling anyway.
>> Tested with tier1-8.
>
> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Make mutex_array be a linked list.

Hi Coleen,

thank you for taking my suggestion.

I still think that this may be better suited for debug only, like the other analysis features of Mutexes, but I leave that up to you. There is a case for making this available in release builds too.

Apart from that, the rest are mostly unimportant nits. I'll leave it up to you what you take from them.

Cheers , Thomas

src/hotspot/share/runtime/mutex.cpp line 273:

> 271: // Array used to print owned locks on error.
> 272: static Mutex* _mutex_array = NULL;
> 273: static int _array_count = 0;

Do we need this counter? Could we not just count the mutexes while printing them?

src/hotspot/share/runtime/mutex.cpp line 280:

> 278:     ThreadCritical tc;
> 279:     Mutex* old_next = _next_mutex;
> 280:     assert(old_next != nullptr, "only static mutexes don't have a next");

This was a brainteaser till I realized that the end of the list is composed of the Mutexes created first, which we don't delete. Maybe add that as a comment?

src/hotspot/share/runtime/mutex.cpp line 322:

> 320:     }
> 321:     _array_count += 1;
> 322:   }

Proposal: maybe factor this block (and its counterpart in ~Mutex) to an own private method, "add_to_global_mutex_list" and "remove_from_global_mutex_list"? That would also make the difference between `_next` and `_next_mutex` a bit clearer to the casual reader.

src/hotspot/share/runtime/mutex.cpp line 335:

> 333: #ifdef ASSERT
> 334:   if (_allow_vm_block) {
> 335:     st->print("%s", " allow_vm_block");

nit: shorten to `print_raw(" alloc_vm_block")` ?

src/hotspot/share/runtime/mutex.cpp line 344:

> 342: // Print all mutexes/monitors that are currently owned by a thread; called
> 343: // by fatal error handler.
> 344: void Mutex::print_owned_locks_on_error(outputStream* st) {

Maybe a small comment that we explicitly avoid locking here, because we are in error handling and locking may block? That we rather risk a secondary crash instead of blocking in error handling?

src/hotspot/share/runtime/mutex.cpp line 345:

> 343: // by fatal error handler.
> 344: void Mutex::print_owned_locks_on_error(outputStream* st) {
> 345:   ResourceMark rm;

Why is this mark needed?

src/hotspot/share/runtime/mutex.cpp line 346:

> 344: void Mutex::print_owned_locks_on_error(outputStream* st) {
> 345:   ResourceMark rm;
> 346:   st->print("VM Mutex/Monitor currently owned by a thread: ");

nit: use plural? 
e.g. "All VM Mutexes/Monitors currently owned by any thread:"

src/hotspot/share/runtime/mutex.cpp line 361:

> 359:   }
> 360:   if (none) st->print_cr("None");
> 361:   st->print_cr("Total Mutex count %d", _array_count);

This prints the total number of mutexes, not those owned by a thread, is that intentional?

src/hotspot/share/utilities/vmError.cpp line 1920:

> 1918:       MutexLocker ml(ErrorTest_lock, Mutex::_no_safepoint_check_flag);
> 1919:       assert(how == 0, "test assert with lock");
> 1920:       break;

I like this test.

-------------

PR: https://git.openjdk.java.net/jdk/pull/5958


More information about the hotspot-dev mailing list