Skip to content

Commit 4e725ba

Browse files
committed
Auto merge of #97191 - wesleywiser:main_thread_name, r=ChrisDenton
Call the OS function to set the main thread's name on program init Normally, `Thread::spawn` takes care of setting the thread's name, if one was provided, but since the main thread wasn't created by calling `Thread::spawn`, we need to call that function in `std::rt::init`. This is mainly useful for system tools like debuggers and profilers which might show the thread name to a user. Prior to these changes, gdb and WinDbg would show all thread names except the main thread's name to a user. I've validated that this patch resolves the issue for both debuggers.
2 parents 3a8e713 + cb87ce2 commit 4e725ba

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

Diff for: library/std/src/sys/unix/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![allow(missing_docs, nonstandard_style)]
22

3+
use crate::ffi::CStr;
34
use crate::io::ErrorKind;
45

56
pub use self::rand::hashmap_random_keys;
@@ -66,6 +67,15 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
6667
stack_overflow::init();
6768
args::init(argc, argv);
6869

70+
// Normally, `thread::spawn` will call `Thread::set_name` but since this thread
71+
// already exists, we have to call it ourselves. We only do this on macos
72+
// because some unix-like operating systems such as Linux share process-id and
73+
// thread-id for the main thread and so renaming the main thread will rename the
74+
// process and we only want to enable this on platforms we've tested.
75+
if cfg!(target_os = "macos") {
76+
thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0"));
77+
}
78+
6979
unsafe fn sanitize_standard_fds() {
7080
#[cfg(not(miri))]
7181
// The standard fds are always available in Miri.

Diff for: library/std/src/sys/windows/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(missing_docs, nonstandard_style)]
22

3-
use crate::ffi::{OsStr, OsString};
3+
use crate::ffi::{CStr, OsStr, OsString};
44
use crate::io::ErrorKind;
55
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
66
use crate::path::PathBuf;
@@ -49,6 +49,10 @@ cfg_if::cfg_if! {
4949
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
5050
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
5151
stack_overflow::init();
52+
53+
// Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
54+
// exists, we have to call it ourselves.
55+
thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0"));
5256
}
5357

5458
// SAFETY: must be called only once during runtime cleanup.

Diff for: src/test/debuginfo/thread-names.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// compile-flags:-g
2+
// We can't set the main thread name on Linux because it renames the process (#97191)
3+
// ignore-linux
4+
// ignore-android
5+
// ignore-dragonfly
6+
// ignore-emscripten
7+
// ignore-freebsd
8+
// ignore-haiku
9+
// ignore-ios
10+
// ignore-netbsd
11+
// ignore-openbsd
12+
// ignore-solaris
13+
// ignore-sgx
14+
// ignore-windows-gnu
15+
16+
// === GDB TESTS ==================================================================================
17+
//
18+
// gdb-command:run
19+
//
20+
// gdb-command:info threads
21+
// gdb-check: 1 Thread [...] [...] "main" [...]
22+
// gdb-check:* 2 Thread [...] [...] "my new thread" [...]
23+
24+
// === LLDB TESTS =================================================================================
25+
//
26+
// lldb-command:run
27+
//
28+
// lldb-command:thread info 1
29+
// lldb-check:thread #1:[...]name = 'main'[...]
30+
// lldb-command:thread info 2
31+
// lldb-check:thread #2:[...]name = 'my new thread'[...]
32+
33+
// === CDB TESTS ==================================================================================
34+
//
35+
// cdb-command:g
36+
//
37+
// cdb-command:~
38+
// cdb-check: 0 Id: [...] Suspend: 1 Teb: [...] Unfrozen "main"
39+
// cdb-check:. [...] Id: [...] Suspend: 1 Teb: [...] Unfrozen "my new thread"
40+
41+
use std::thread;
42+
43+
fn main() {
44+
let handle = thread::Builder::new().name("my new thread".into()).spawn(|| {
45+
zzz(); // #break
46+
}).unwrap();
47+
48+
handle.join().unwrap();
49+
}
50+
51+
fn zzz() {}

0 commit comments

Comments
 (0)