Skip to content

Commit 820ffc8

Browse files
committed
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.
1 parent c067287 commit 820ffc8

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

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.

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.

src/test/debuginfo/thread-names.rs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
5+
// === GDB TESTS ==================================================================================
6+
//
7+
// gdb-command:run
8+
//
9+
// gdb-command:info threads
10+
// gdb-check: 1 Thread [...] [...] "main" [...]
11+
// gdb-check:* 2 Thread [...] [...] "my new thread" [...]
12+
13+
// === LLDB TESTS =================================================================================
14+
//
15+
// lldb-command:run
16+
//
17+
// lldb-command:thread info 1
18+
// lldb-check:thread #1:[...]name = 'main'[...]
19+
// lldb-command:thread info 2
20+
// lldb-check:thread #2:[...]name = 'my new thread'[...]
21+
22+
// === CDB TESTS ==================================================================================
23+
//
24+
// cdb-command:g
25+
//
26+
// cdb-command:~
27+
// cdb-check: 0 Id: [...] Suspend: 1 Teb: [...] Unfrozen "main"
28+
// cdb-check:. [...] Id: [...] Suspend: 1 Teb: [...] Unfrozen "my new thread"
29+
30+
use std::thread;
31+
32+
fn main() {
33+
let handle = thread::Builder::new().name("my new thread".into()).spawn(|| {
34+
zzz(); // #break
35+
}).unwrap();
36+
37+
handle.join().unwrap();
38+
}
39+
40+
fn zzz() {}

0 commit comments

Comments
 (0)