Skip to content

Commit

Permalink
Call the OS function to set the main thread's name on program init
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wesleywiser committed May 27, 2022
1 parent c067287 commit 820ffc8
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
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
40 changes: 40 additions & 0 deletions src/test/debuginfo/thread-names.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// compile-flags:-g
// We can't set the main thread name on Linux because it renames the process (#97191)
// ignore-linux

// === 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() {}

0 comments on commit 820ffc8

Please sign in to comment.