Call new Win32 API SetThreadDescription in os::set_native_thread_name

David Holmes david.holmes at oracle.com
Fri Feb 7 02:00:12 UTC 2020


Hi Markus,

Adding hotspot-runtime-dev as runtime owns this area of code.

On 7/02/2020 4:07 am, Gaisbauer, Markus wrote:
> Hi,
> 
> I am looking for a sponsor who could create a ticket for the following proposal:

Have you signed the OCA?

https://www.oracle.com/technetwork/community/oca-486395.html

I don't see you listed.

> Microsoft recently introduced a new API to assign a name to native Windows threads.
> https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
> 
> These thread names can be shown by debuggers, C++ profilers, etc. The new API is available since either Windows 10 1607 or Windows Server 2016.

Thanks for that heads up about the new API. I have filed:

https://bugs.openjdk.java.net/browse/JDK-8238649

for that enhancement.

Thanks,
David
-----

> The JVM already tries to set a native thread name both for all internal JVM threads and all Java threads (except main).
> 
> But the Windows implementation of os::set_native_thread_name currently uses a weird hack described here.
> https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2015&redirectedfrom=MSDN
> 
> For this hack, debugger has to be already attached when a thread starts.
> 
> I propose to check in os::set_native_thread_name if SetThreadDescription is available. If yes, either call it instead or in addition to the current code.
> 
> Here is some prototype code that worked for me:
> 
> typedef HRESULT(WINAPI *SetThreadDescriptionT)(HANDLE, PCWSTR);
> 
> static SetThreadDescriptionT getSetThreadDescriptionT() {
>    HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
>    return kernel32 ? reinterpret_cast<SetThreadDescriptionT>(GetProcAddress(kernel32, "SetThreadDescription")) : nullptr;
> }
> 
> static LPWSTR utf8_decode(const char *name) {
>    if (name == nullptr) return nullptr;
>    int name_len = (int) strlen(name);
>    int size_needed = MultiByteToWideChar(CP_UTF8, 0, name, name_len, NULL, 0);
>    size_t buffer_len = sizeof(wchar_t) * (size_needed + 1);
>    LPWSTR result = (LPWSTR) os::malloc(buffer_len, mtInternal);
>    memset(result, 0, buffer_len);
>    MultiByteToWideChar(CP_UTF8, 0, name, name_len, result, size_needed);
>    return result;
> }
> 
> void os::set_native_thread_name(const char *name) {
> 
>    // First try calling SetThreadDescription available since Windows 10 1607 / Windows Server 2016
>    // See: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
> 
>    static SetThreadDescriptionT SetThreadDescription = getSetThreadDescriptionT();
>    if (SetThreadDescription) {
>      LPWSTR nameWide = utf8_decode(name);
>      if (nameWide != nullptr) {
>        SetThreadDescription(GetCurrentThread(), nameWide);
>        os::free(nameWide);
>      }
>      return;
>    }
> 
>    // fallback
>    ...
> }
> 
> Best regards,
> Markus
> The contents of this e-mail are intended for the named addressee only. It contains information that may be confidential. Unless you are the named addressee or an authorized designee, you may not copy or use it, or disclose it to anyone else. If you received it in error please notify us immediately and then destroy it. Dynatrace Austria GmbH (registration number FN 91482h) is a company registered in Linz whose registered office is at 4020 Linz, Austria, Am Fünfundzwanziger Turm 20
> 


More information about the hotspot-runtime-dev mailing list