Skip to content

Commit e385ea6

Browse files
authored
Rollup merge of rust-lang#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 6385b1d + 7cb538b commit e385ea6

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-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

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

0 commit comments

Comments
 (0)