Skip to content

Call the OS function to set the main thread's name on program init #97191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions library/std/src/sys/unix/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(missing_docs, nonstandard_style)]

use crate::ffi::CStr;
use crate::io::ErrorKind;

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

// Normally, `thread::spawn` will call `Thread::set_name` but since this thread
// already exists, we have to call it ourselves. We only do this on macos
// because some unix-like operating systems such as Linux share process-id and
// thread-id for the main thread and so renaming the main thread will rename the
// process and we only want to enable this on platforms we've tested.
if cfg!(target_os = "macos") {
thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0"));
}

unsafe fn sanitize_standard_fds() {
#[cfg(not(miri))]
// The standard fds are always available in Miri.
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/windows/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(missing_docs, nonstandard_style)]

use crate::ffi::{OsStr, OsString};
use crate::ffi::{CStr, OsStr, OsString};
use crate::io::ErrorKind;
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
use crate::path::PathBuf;
Expand Down Expand Up @@ -49,6 +49,10 @@ cfg_if::cfg_if! {
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
stack_overflow::init();

// Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
// exists, we have to call it ourselves.
thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0"));
}

// SAFETY: must be called only once during runtime cleanup.
Expand Down
51 changes: 51 additions & 0 deletions src/test/debuginfo/thread-names.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// compile-flags:-g
// We can't set the main thread name on Linux because it renames the process (#97191)
// ignore-linux
// ignore-android
// ignore-dragonfly
// ignore-emscripten
// ignore-freebsd
// ignore-haiku
// ignore-ios
// ignore-netbsd
// ignore-openbsd
// ignore-solaris
// ignore-sgx
// ignore-windows-gnu

// === GDB TESTS ==================================================================================
//
// gdb-command:run
//
// gdb-command:info threads
// gdb-check: 1 Thread [...] [...] "main" [...]
// gdb-check:* 2 Thread [...] [...] "my new thread" [...]

// === LLDB TESTS =================================================================================
//
// lldb-command:run
//
// lldb-command:thread info 1
// lldb-check:thread #1:[...]name = 'main'[...]
// lldb-command:thread info 2
// lldb-check:thread #2:[...]name = 'my new thread'[...]

// === CDB TESTS ==================================================================================
//
// cdb-command:g
//
// cdb-command:~
// cdb-check: 0 Id: [...] Suspend: 1 Teb: [...] Unfrozen "main"
// cdb-check:. [...] Id: [...] Suspend: 1 Teb: [...] Unfrozen "my new thread"

use std::thread;

fn main() {
let handle = thread::Builder::new().name("my new thread".into()).spawn(|| {
zzz(); // #break
}).unwrap();

handle.join().unwrap();
}

fn zzz() {}