Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8238649

Call new Win32 API SetThreadDescription in os::set_native_thread_name

XMLWordPrintable

    • b02
    • x86
    • windows_10

        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:
        >
        > 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.
        >
        > 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

              dholmes David Holmes
              dholmes David Holmes
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: