[PATCH v3 07/20] util: add API to fetch the current thread name

Daniel P. Berrangé posted 20 patches 2 weeks, 3 days ago
Maintainers: Gerd Hoffmann <kraxel@redhat.com>, Christian Schoenebeck <qemu_oss@crudebyte.com>, Markus Armbruster <armbru@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, "Dr. David Alan Gilbert" <dave@treblig.org>, Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Stefan Weil <sw@weilnetz.de>
There is a newer version of this series
[PATCH v3 07/20] util: add API to fetch the current thread name
Posted by Daniel P. Berrangé 2 weeks, 3 days ago
This will be used to include the thread name in error reports
in a later patch. It returns a const string stored in a thread
local to avoid memory allocation when it is called repeatedly
in a single thread. This makes the assumption that the thread
name is set at the very start of the thread, which is the case
when using qemu_thread_create.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 include/qemu/thread.h    |  1 +
 meson.build              | 21 +++++++++++++++++
 util/qemu-thread-posix.c | 28 ++++++++++++++++++++++-
 util/qemu-thread-win32.c | 49 ++++++++++++++++++++++++++++++++++++----
 4 files changed, 94 insertions(+), 5 deletions(-)

diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 27b888ab0a..98cc5c41ac 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -216,6 +216,7 @@ void qemu_thread_get_self(QemuThread *thread);
 bool qemu_thread_is_self(QemuThread *thread);
 G_NORETURN void qemu_thread_exit(void *retval);
 void qemu_thread_set_name(const char *name);
+const char *qemu_thread_get_name(void);
 
 struct Notifier;
 /**
diff --git a/meson.build b/meson.build
index fa6186db33..6aa673f4b2 100644
--- a/meson.build
+++ b/meson.build
@@ -2920,6 +2920,27 @@ config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(osdep_prefix + '''
     pthread_set_name_np(thread, "QEMU");
     return 0;
   }''', dependencies: threads))
+
+config_host_data.set('CONFIG_PTHREAD_GETNAME_NP', cc.links(osdep_prefix + '''
+  #include <pthread.h>
+
+  int main(void)
+  {
+    char buf[16];
+    pthread_getname_np(pthread_self(), buf, sizeof(buf));
+    return 0;
+  }''', dependencies: threads))
+config_host_data.set('CONFIG_PTHREAD_GET_NAME_NP', cc.links(osdep_prefix + '''
+  #include <pthread.h>
+  #include <pthread_np.h>
+
+  int main(void)
+  {
+    char buf[16];
+    pthread_get_name_np(pthread_self(), buf, sizeof(buf));
+    return 0;
+  }''', dependencies: threads))
+
 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(osdep_prefix + '''
   #include <pthread.h>
 
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 275445ed94..fbb94ca97b 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -18,7 +18,7 @@
 #include "qemu/tsan.h"
 #include "qemu/bitmap.h"
 
-#ifdef CONFIG_PTHREAD_SET_NAME_NP
+#if defined(CONFIG_PTHREAD_SET_NAME_NP) || defined(CONFIG_PTHREAD_GET_NAME_NP)
 #include <pthread_np.h>
 #endif
 
@@ -532,3 +532,29 @@ void *qemu_thread_join(QemuThread *thread)
     }
     return ret;
 }
+
+#ifndef PTHREAD_MAX_NAMELEN_NP
+#define PTHREAD_MAX_NAMELEN_NP 16
+#endif
+
+static __thread char namebuf[PTHREAD_MAX_NAMELEN_NP];
+
+const char *qemu_thread_get_name(void)
+{
+    int rv;
+    if (namebuf[0] != '\0') {
+        return namebuf;
+    }
+
+# if defined(CONFIG_PTHREAD_GETNAME_NP)
+    rv = pthread_getname_np(pthread_self(), namebuf, sizeof(namebuf));
+# elif defined(CONFIG_PTHREAD_GET_NAME_NP)
+    rv = pthread_get_name_np(pthread_self(), namebuf, sizeof(namebuf));
+# else
+    rv = -1;
+# endif
+    if (rv != 0) {
+        strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
+    }
+    return namebuf;
+}
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index 7a734a7a09..e3789c20d1 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -19,7 +19,10 @@
 
 typedef HRESULT (WINAPI *pSetThreadDescription) (HANDLE hThread,
                                                  PCWSTR lpThreadDescription);
+typedef HRESULT (WINAPI *pGetThreadDescription) (HANDLE hThread,
+                                                 PWSTR *lpThreadDescription);
 static pSetThreadDescription SetThreadDescriptionFunc;
+static pGetThreadDescription GetThreadDescriptionFunc;
 static HMODULE kernel32_module;
 
 static void __attribute__((__constructor__(QEMU_CONSTRUCTOR_EARLY)))
@@ -28,7 +31,7 @@ qemu_thread_init(void)
     qemu_thread_set_name("main");
 }
 
-static bool load_set_thread_description(void)
+static bool load_thread_description(void)
 {
     static gsize _init_once = 0;
 
@@ -38,14 +41,17 @@ static bool load_set_thread_description(void)
             SetThreadDescriptionFunc =
                 (pSetThreadDescription)GetProcAddress(kernel32_module,
                                                       "SetThreadDescription");
-            if (!SetThreadDescriptionFunc) {
+            GetThreadDescriptionFunc =
+                (pGetThreadDescription)GetProcAddress(kernel32_module,
+                                                      "GetThreadDescription");
+            if (!SetThreadDescriptionFunc || !GetThreadDescriptionFunc) {
                 FreeLibrary(kernel32_module);
             }
         }
         g_once_init_leave(&_init_once, 1);
     }
 
-    return !!SetThreadDescriptionFunc;
+    return !!(SetThreadDescriptionFunc && GetThreadDescriptionFunc);
 }
 
 static void error_exit(int err, const char *msg)
@@ -326,7 +332,7 @@ void qemu_thread_set_name(const char *name)
 {
     g_autofree wchar_t *namew = NULL;
 
-    if (!load_set_thread_description()) {
+    if (!load_thread_description()) {
         return;
     }
 
@@ -412,3 +418,38 @@ bool qemu_thread_is_self(QemuThread *thread)
 {
     return GetCurrentThreadId() == thread->tid;
 }
+
+static __thread char namebuf[64];
+
+const char *qemu_thread_get_name(void)
+{
+    HRESULT hr;
+    wchar_t *namew = NULL;
+    g_autofree char *name = NULL;
+
+    if (namebuf[0] != '\0') {
+        return namebuf;
+    }
+
+    if (!load_thread_description()) {
+        goto error;
+    }
+
+    hr = GetThreadDescriptionFunc(GetCurrentThread(), &namew);
+    if (!SUCCEEDED(hr)) {
+        goto error;
+    }
+
+    name = g_utf16_to_utf8(namew, -1, NULL, NULL, NULL);
+    LocalFree(namew);
+    if (!name) {
+        goto error;
+    }
+
+    g_strlcpy(namebuf, name, G_N_ELEMENTS(namebuf));
+    return namebuf;
+
+ error:
+    strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
+    return namebuf;
+}
-- 
2.50.1


Re: [PATCH v3 07/20] util: add API to fetch the current thread name
Posted by Markus Armbruster 5 days, 4 hours ago
Daniel P. Berrangé <berrange@redhat.com> writes:

> This will be used to include the thread name in error reports
> in a later patch. It returns a const string stored in a thread
> local to avoid memory allocation when it is called repeatedly
> in a single thread. This makes the assumption that the thread
> name is set at the very start of the thread, which is the case
> when using qemu_thread_create.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

[...]

> diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
> index 7a734a7a09..e3789c20d1 100644
> --- a/util/qemu-thread-win32.c
> +++ b/util/qemu-thread-win32.c

[...]

> @@ -412,3 +418,38 @@ bool qemu_thread_is_self(QemuThread *thread)
>  {
>      return GetCurrentThreadId() == thread->tid;
>  }
> +
> +static __thread char namebuf[64];
> +
> +const char *qemu_thread_get_name(void)
> +{
> +    HRESULT hr;
> +    wchar_t *namew = NULL;
> +    g_autofree char *name = NULL;
> +
> +    if (namebuf[0] != '\0') {
> +        return namebuf;
> +    }
> +
> +    if (!load_thread_description()) {
> +        goto error;
> +    }
> +
> +    hr = GetThreadDescriptionFunc(GetCurrentThread(), &namew);
> +    if (!SUCCEEDED(hr)) {
> +        goto error;
> +    }
> +
> +    name = g_utf16_to_utf8(namew, -1, NULL, NULL, NULL);
> +    LocalFree(namew);
> +    if (!name) {
> +        goto error;
> +    }
> +
> +    g_strlcpy(namebuf, name, G_N_ELEMENTS(namebuf));
> +    return namebuf;
> +
> + error:
> +    strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
> +    return namebuf;
> +}

../util/qemu-thread-win32.c: In function 'qemu_thread_get_name':
../util/qemu-thread-win32.c:453:5: error: implicit declaration of function 'strlcpy'; did you mean 'strncpy'? [-Wimplicit-function-declaration]
  453 |     strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
      |     ^~~~~~~
      |     strncpy
../util/qemu-thread-win32.c:453:5: error: nested extern declaration of 'strlcpy' [-Werror=nested-externs]
Re: [PATCH v3 07/20] util: add API to fetch the current thread name
Posted by Daniel P. Berrangé 4 days, 8 hours ago
On Tue, Sep 23, 2025 at 02:12:02PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
> 
> > This will be used to include the thread name in error reports
> > in a later patch. It returns a const string stored in a thread
> > local to avoid memory allocation when it is called repeatedly
> > in a single thread. This makes the assumption that the thread
> > name is set at the very start of the thread, which is the case
> > when using qemu_thread_create.
> >
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> 
> [...]
> 
> > diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
> > index 7a734a7a09..e3789c20d1 100644
> > --- a/util/qemu-thread-win32.c
> > +++ b/util/qemu-thread-win32.c
> 
> [...]
> 
> > @@ -412,3 +418,38 @@ bool qemu_thread_is_self(QemuThread *thread)
> >  {
> >      return GetCurrentThreadId() == thread->tid;
> >  }
> > +
> > +static __thread char namebuf[64];
> > +
> > +const char *qemu_thread_get_name(void)
> > +{
> > +    HRESULT hr;
> > +    wchar_t *namew = NULL;
> > +    g_autofree char *name = NULL;
> > +
> > +    if (namebuf[0] != '\0') {
> > +        return namebuf;
> > +    }
> > +
> > +    if (!load_thread_description()) {
> > +        goto error;
> > +    }
> > +
> > +    hr = GetThreadDescriptionFunc(GetCurrentThread(), &namew);
> > +    if (!SUCCEEDED(hr)) {
> > +        goto error;
> > +    }
> > +
> > +    name = g_utf16_to_utf8(namew, -1, NULL, NULL, NULL);
> > +    LocalFree(namew);
> > +    if (!name) {
> > +        goto error;
> > +    }
> > +
> > +    g_strlcpy(namebuf, name, G_N_ELEMENTS(namebuf));
> > +    return namebuf;
> > +
> > + error:
> > +    strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
> > +    return namebuf;
> > +}
> 
> ../util/qemu-thread-win32.c: In function 'qemu_thread_get_name':
> ../util/qemu-thread-win32.c:453:5: error: implicit declaration of function 'strlcpy'; did you mean 'strncpy'? [-Wimplicit-function-declaration]
>   453 |     strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
>       |     ^~~~~~~
>       |     strncpy
> ../util/qemu-thread-win32.c:453:5: error: nested extern declaration of 'strlcpy' [-Werror=nested-externs]

Sigh, I meant g_strlcopy like the line shortly before.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Re: [PATCH v3 07/20] util: add API to fetch the current thread name
Posted by Markus Armbruster 1 week, 2 days ago
Daniel P. Berrangé <berrange@redhat.com> writes:

> This will be used to include the thread name in error reports
> in a later patch. It returns a const string stored in a thread
> local to avoid memory allocation when it is called repeatedly
> in a single thread. This makes the assumption that the thread
> name is set at the very start of the thread, which is the case
> when using qemu_thread_create.

What happens when the assumption is violated?

> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  include/qemu/thread.h    |  1 +
>  meson.build              | 21 +++++++++++++++++
>  util/qemu-thread-posix.c | 28 ++++++++++++++++++++++-
>  util/qemu-thread-win32.c | 49 ++++++++++++++++++++++++++++++++++++----
>  4 files changed, 94 insertions(+), 5 deletions(-)
>
> diff --git a/include/qemu/thread.h b/include/qemu/thread.h
> index 27b888ab0a..98cc5c41ac 100644
> --- a/include/qemu/thread.h
> +++ b/include/qemu/thread.h
> @@ -216,6 +216,7 @@ void qemu_thread_get_self(QemuThread *thread);
>  bool qemu_thread_is_self(QemuThread *thread);
>  G_NORETURN void qemu_thread_exit(void *retval);
>  void qemu_thread_set_name(const char *name);
> +const char *qemu_thread_get_name(void);
>  
>  struct Notifier;
>  /**
> diff --git a/meson.build b/meson.build
> index fa6186db33..6aa673f4b2 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2920,6 +2920,27 @@ config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(osdep_prefix + '''
>      pthread_set_name_np(thread, "QEMU");
>      return 0;
>    }''', dependencies: threads))
> +
> +config_host_data.set('CONFIG_PTHREAD_GETNAME_NP', cc.links(osdep_prefix + '''
> +  #include <pthread.h>
> +
> +  int main(void)
> +  {
> +    char buf[16];
> +    pthread_getname_np(pthread_self(), buf, sizeof(buf));
> +    return 0;
> +  }''', dependencies: threads))
> +config_host_data.set('CONFIG_PTHREAD_GET_NAME_NP', cc.links(osdep_prefix + '''
> +  #include <pthread.h>
> +  #include <pthread_np.h>
> +
> +  int main(void)
> +  {
> +    char buf[16];
> +    pthread_get_name_np(pthread_self(), buf, sizeof(buf));
> +    return 0;
> +  }''', dependencies: threads))
> +
>  config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(osdep_prefix + '''
>    #include <pthread.h>
>  
> diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
> index 275445ed94..fbb94ca97b 100644
> --- a/util/qemu-thread-posix.c
> +++ b/util/qemu-thread-posix.c
> @@ -18,7 +18,7 @@
>  #include "qemu/tsan.h"
>  #include "qemu/bitmap.h"
>  
> -#ifdef CONFIG_PTHREAD_SET_NAME_NP
> +#if defined(CONFIG_PTHREAD_SET_NAME_NP) || defined(CONFIG_PTHREAD_GET_NAME_NP)
>  #include <pthread_np.h>
>  #endif
>  
> @@ -532,3 +532,29 @@ void *qemu_thread_join(QemuThread *thread)
>      }
>      return ret;
>  }
> +
> +#ifndef PTHREAD_MAX_NAMELEN_NP
> +#define PTHREAD_MAX_NAMELEN_NP 16

Feels a bit tight.  32?

> +#endif
> +
> +static __thread char namebuf[PTHREAD_MAX_NAMELEN_NP];
> +
> +const char *qemu_thread_get_name(void)
> +{
> +    int rv;
> +    if (namebuf[0] != '\0') {
> +        return namebuf;
> +    }
> +
> +# if defined(CONFIG_PTHREAD_GETNAME_NP)
> +    rv = pthread_getname_np(pthread_self(), namebuf, sizeof(namebuf));
> +# elif defined(CONFIG_PTHREAD_GET_NAME_NP)
> +    rv = pthread_get_name_np(pthread_self(), namebuf, sizeof(namebuf));
> +# else
> +    rv = -1;
> +# endif
> +    if (rv != 0) {
> +        strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
> +    }
> +    return namebuf;
> +}
> diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
> index 7a734a7a09..e3789c20d1 100644
> --- a/util/qemu-thread-win32.c
> +++ b/util/qemu-thread-win32.c
> @@ -19,7 +19,10 @@
>  
>  typedef HRESULT (WINAPI *pSetThreadDescription) (HANDLE hThread,
>                                                   PCWSTR lpThreadDescription);
> +typedef HRESULT (WINAPI *pGetThreadDescription) (HANDLE hThread,
> +                                                 PWSTR *lpThreadDescription);
>  static pSetThreadDescription SetThreadDescriptionFunc;
> +static pGetThreadDescription GetThreadDescriptionFunc;
>  static HMODULE kernel32_module;
>  
>  static void __attribute__((__constructor__(QEMU_CONSTRUCTOR_EARLY)))
> @@ -28,7 +31,7 @@ qemu_thread_init(void)
>      qemu_thread_set_name("main");
>  }
>  
> -static bool load_set_thread_description(void)
> +static bool load_thread_description(void)
>  {
>      static gsize _init_once = 0;
>  
> @@ -38,14 +41,17 @@ static bool load_set_thread_description(void)
>              SetThreadDescriptionFunc =
>                  (pSetThreadDescription)GetProcAddress(kernel32_module,
>                                                        "SetThreadDescription");
> -            if (!SetThreadDescriptionFunc) {
> +            GetThreadDescriptionFunc =
> +                (pGetThreadDescription)GetProcAddress(kernel32_module,
> +                                                      "GetThreadDescription");
> +            if (!SetThreadDescriptionFunc || !GetThreadDescriptionFunc) {
>                  FreeLibrary(kernel32_module);
>              }
>          }
>          g_once_init_leave(&_init_once, 1);
>      }
>  
> -    return !!SetThreadDescriptionFunc;
> +    return !!(SetThreadDescriptionFunc && GetThreadDescriptionFunc);
>  }
>  
>  static void error_exit(int err, const char *msg)
> @@ -326,7 +332,7 @@ void qemu_thread_set_name(const char *name)
>  {
>      g_autofree wchar_t *namew = NULL;
>  
> -    if (!load_set_thread_description()) {
> +    if (!load_thread_description()) {
>          return;
>      }
>  
> @@ -412,3 +418,38 @@ bool qemu_thread_is_self(QemuThread *thread)
>  {
>      return GetCurrentThreadId() == thread->tid;
>  }
> +
> +static __thread char namebuf[64];
> +
> +const char *qemu_thread_get_name(void)
> +{
> +    HRESULT hr;
> +    wchar_t *namew = NULL;
> +    g_autofree char *name = NULL;
> +
> +    if (namebuf[0] != '\0') {
> +        return namebuf;
> +    }
> +
> +    if (!load_thread_description()) {
> +        goto error;
> +    }
> +
> +    hr = GetThreadDescriptionFunc(GetCurrentThread(), &namew);
> +    if (!SUCCEEDED(hr)) {
> +        goto error;
> +    }
> +
> +    name = g_utf16_to_utf8(namew, -1, NULL, NULL, NULL);
> +    LocalFree(namew);
> +    if (!name) {
> +        goto error;
> +    }
> +
> +    g_strlcpy(namebuf, name, G_N_ELEMENTS(namebuf));
> +    return namebuf;
> +
> + error:
> +    strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
> +    return namebuf;
> +}
Re: [PATCH v3 07/20] util: add API to fetch the current thread name
Posted by Daniel P. Berrangé 1 week, 2 days ago
On Fri, Sep 19, 2025 at 10:59:18AM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
> 
> > This will be used to include the thread name in error reports
> > in a later patch. It returns a const string stored in a thread
> > local to avoid memory allocation when it is called repeatedly
> > in a single thread. This makes the assumption that the thread
> > name is set at the very start of the thread, which is the case
> > when using qemu_thread_create.
> 
> What happens when the assumption is violated?

You will get an operating system default thread name,
which on Linux will default to the unqualified binary
name based on argv[0]

> 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> >  include/qemu/thread.h    |  1 +
> >  meson.build              | 21 +++++++++++++++++
> >  util/qemu-thread-posix.c | 28 ++++++++++++++++++++++-
> >  util/qemu-thread-win32.c | 49 ++++++++++++++++++++++++++++++++++++----
> >  4 files changed, 94 insertions(+), 5 deletions(-)


> > diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
> > index 275445ed94..fbb94ca97b 100644
> > --- a/util/qemu-thread-posix.c
> > +++ b/util/qemu-thread-posix.c
> > @@ -18,7 +18,7 @@
> >  #include "qemu/tsan.h"
> >  #include "qemu/bitmap.h"
> >  
> > -#ifdef CONFIG_PTHREAD_SET_NAME_NP
> > +#if defined(CONFIG_PTHREAD_SET_NAME_NP) || defined(CONFIG_PTHREAD_GET_NAME_NP)
> >  #include <pthread_np.h>
> >  #endif
> >  
> > @@ -532,3 +532,29 @@ void *qemu_thread_join(QemuThread *thread)
> >      }
> >      return ret;
> >  }
> > +
> > +#ifndef PTHREAD_MAX_NAMELEN_NP
> > +#define PTHREAD_MAX_NAMELEN_NP 16
> 
> Feels a bit tight.  32?

On Linux this constant is not defined, but the manpage says

  The thread name is a meaningful C language string, whose length is
  restricted to 16 characters, including the terminating null byte ('\0')

so I defined the constant to match the non-Linux constant
name, but with the Linux documented max length.

> 
> > +#endif
> > +
> > +static __thread char namebuf[PTHREAD_MAX_NAMELEN_NP];
> > +
> > +const char *qemu_thread_get_name(void)
> > +{
> > +    int rv;
> > +    if (namebuf[0] != '\0') {
> > +        return namebuf;
> > +    }
> > +
> > +# if defined(CONFIG_PTHREAD_GETNAME_NP)
> > +    rv = pthread_getname_np(pthread_self(), namebuf, sizeof(namebuf));
> > +# elif defined(CONFIG_PTHREAD_GET_NAME_NP)
> > +    rv = pthread_get_name_np(pthread_self(), namebuf, sizeof(namebuf));
> > +# else
> > +    rv = -1;
> > +# endif
> > +    if (rv != 0) {
> > +        strlcpy(namebuf, "unnamed", G_N_ELEMENTS(namebuf));
> > +    }
> > +    return namebuf;
> > +}

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Re: [PATCH v3 07/20] util: add API to fetch the current thread name
Posted by Markus Armbruster 1 week, 2 days ago
Daniel P. Berrangé <berrange@redhat.com> writes:

> On Fri, Sep 19, 2025 at 10:59:18AM +0200, Markus Armbruster wrote:
>> Daniel P. Berrangé <berrange@redhat.com> writes:
>> 
>> > This will be used to include the thread name in error reports
>> > in a later patch. It returns a const string stored in a thread
>> > local to avoid memory allocation when it is called repeatedly
>> > in a single thread. This makes the assumption that the thread
>> > name is set at the very start of the thread, which is the case
>> > when using qemu_thread_create.
>> 
>> What happens when the assumption is violated?
>
> You will get an operating system default thread name,
> which on Linux will default to the unqualified binary
> name based on argv[0]

Suggest something like "The thread name should be set at the very start
of the thread, which is the case when using qemu_thread_create."

>> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>> > ---
>> >  include/qemu/thread.h    |  1 +
>> >  meson.build              | 21 +++++++++++++++++
>> >  util/qemu-thread-posix.c | 28 ++++++++++++++++++++++-
>> >  util/qemu-thread-win32.c | 49 ++++++++++++++++++++++++++++++++++++----
>> >  4 files changed, 94 insertions(+), 5 deletions(-)
>
>
>> > diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
>> > index 275445ed94..fbb94ca97b 100644
>> > --- a/util/qemu-thread-posix.c
>> > +++ b/util/qemu-thread-posix.c
>> > @@ -18,7 +18,7 @@
>> >  #include "qemu/tsan.h"
>> >  #include "qemu/bitmap.h"
>> >  
>> > -#ifdef CONFIG_PTHREAD_SET_NAME_NP
>> > +#if defined(CONFIG_PTHREAD_SET_NAME_NP) || defined(CONFIG_PTHREAD_GET_NAME_NP)
>> >  #include <pthread_np.h>
>> >  #endif
>> >  
>> > @@ -532,3 +532,29 @@ void *qemu_thread_join(QemuThread *thread)
>> >      }
>> >      return ret;
>> >  }
>> > +
>> > +#ifndef PTHREAD_MAX_NAMELEN_NP
>> > +#define PTHREAD_MAX_NAMELEN_NP 16
>> 
>> Feels a bit tight.  32?
>
> On Linux this constant is not defined, but the manpage says
>
>   The thread name is a meaningful C language string, whose length is
>   restricted to 16 characters, including the terminating null byte ('\0')
>
> so I defined the constant to match the non-Linux constant
> name, but with the Linux documented max length.

I see.

Maybe mention in a comment or the commit message?

[...]