Opened 5 years ago

Last modified 2 years ago

#11245 confirmed enhancement

Allow setting wxThread name

Reported by: ScratchMonkey Owned by:
Priority: normal Milestone:
Component: base Version:
Keywords: thread name Cc:
Blocked By: Blocking:
Patch: no

Description

It's useful to name threads to make them easy to identify in the debugger, especially when an app might have dozens of threads. This facility is available under Windows and Linux with a 2.6.9+ kernel. It would be nice if wxThread included a method to set a thread's name.

Resources:

General information for several platforms:
http://stackoverflow.com/questions/778085/how-to-name-a-thread-in-linux

MS Windows:
http://msdn.microsoft.com/en-us/library/xcb2z8hs%28VS.80%29.aspx

Linux:
http://manpages.courier-mta.org/htmlman2/prctl.2.html

BSD:
http://www.rootr.net/man/man/pthread_set_name_np/3

Change History (9)

comment:1 Changed 5 years ago by ScratchMonkey

The Windows and BSD variants take a thread identifier as an argument, implying that another thread can set a thread's name. The Linux one is documented as setting the process name but the articles I found indicate it actually sets the name of the current thread. I'll go look at the kernel sources to see what really happens.

There's some degree of uncertainty with some of these APIs about how long the name can be and whether the storage for the string needs to survive for the lifetime of the thread. (The BSD variant is explicitly documented as copying the string for internal use.)

comment:2 Changed 5 years ago by ScratchMonkey

I just finished looking at the Linux kernel source for CentOS package kernel-2.6.18-128.el5.src.rpm.

The implementation copies the provided string to a fixed-size buffer in the internal task (not process, as the man page claims) structure. The copy is done with strlcpy so it truncates and null-terminates the string if necessary. The size of the buffer is TASK_COMM_LEN, defined in <linux/sched.h>, and is 16 for this kernel version.

Files of interest are vanilla/kernel/sys.c, which contains the code for the PR_SET_NAME sub-function, and vanilla/fs/exec.c, which contains set_task_comm() to lock the task structure and copy the string into it.

comment:3 Changed 5 years ago by vadz

  • Status changed from new to confirmed
  • Summary changed from Add wxThread::SetName to Allow setting wxThread name

The main problem I see is that with Linux you can't set the thread name from the outside (16 char limitation is not great neither but we'll just have to live with/document it). In the light of this, we probably need to pass the name to Create() and not have separate SetName() as this would need to be called in the thread context which could be awkward.

But Create() already has a stackSize parameter which won't be used in 99% of cases. So just adding threadName parameter after it would be inconvenient. Instead we probably want to create some wxThreadParameters struct containing both stackSize and threadName and provide a Create() overload taking it. This would be more extensible in case we want to add more thread parameters in the future.

I wonder if we can implement GetName() to retrieve the name of the thread?

comment:4 Changed 5 years ago by ScratchMonkey

I like the idea of a wxThreadParameters structure. If thread priorities are ever implemented, this would be a good place to select the initial thread priority.

Getting the thread name is available under Linux, as it's a kernel property of the task. I've not found evidence of a similar feature under Windows, where the thread name is a feature of the debugger. Looking at how Windows implements this, I suspect the "0x1000" in the passed structure is the "set name" code, but I've not found any other documented uses of the special debugger exception (0x406D1388). The next-best thing is to cache a local copy in the wxThread object for platforms that don't provide a query feature.

I can imagine wanting to change a thread's name during the course of a thread's execution, so having the method available independent of the Create call could be useful. I suggest making it protected, to at least discourage its use from outside the class, and documenting that use from outside the thread is not supported on all platforms.

One possible use case is in a thread pool scenario, where a random idle thread is drawn from a pool to perform a short task. The task class could name the pool thread for the duration of the task. (Because the method would be protected, the pool class would be responsible for exposing this feature to the task class.)

comment:5 Changed 5 years ago by ScratchMonkey

BTW, note that the Linux limitation is 15 characters. The null-terminated buffer is 16 characters long. (If you really wanted more, and you controlled the device your applications runs on, you could change the constant in the header and rebuild the kernel.)

comment:6 Changed 4 years ago by VZ

(In [63008]) Use memmove() instead of memcpy() in wxString::AssignCopy().

This allows the code like "s = s.c_str()" to work correctly, although it
doesn't fix all self-assignment-related bugs.

See #11245.

comment:7 Changed 4 years ago by vadz

Sorry for the above comment, it was meant for #11294 but I used a wrong ticket number.

comment:8 Changed 2 years ago by VZ

(In [70150]) Use memmove() instead of memcpy() in wxString::AssignCopy().

This at least allows the code like "s = s.c_str()" to work correctly when
using our own wxString implementation, even it doesn't fix all
self-assignment-related bugs (again, when using our own implementation only,
there is no bug when using std::basic_string as underlying implementation).

This is a cherry pick of r63008 from 2.8 branch.

See #11245.

comment:9 Changed 2 years ago by vadz

Aaaargh, and the cherry-pick reused the wrong ticket number, of course. Sorry again.

Note: See TracTickets for help on using tickets.