rust-lang/rust · error
valid UTF-8
Error message
valid UTF-8
What it means
Thrown by `CStr::from_ptr(pass_name).to_str().expect("valid UTF-8")` in `selfprofile_before_pass_callback` (profiling.rs:53). This callback runs only when self-profiling (`-Z self-profile` / `-Z self-profile-events`) is enabled; LLVM passes the C-string name of an optimization pass back to rustc, and this expect fires if that name is not valid UTF-8. In practice LLVM pass names are ASCII, so this panic indicates a memory-safety/FFI contract violation or an LLVM build that emitted garbage pass names.
Source
Thrown at compiler/rustc_codegen_llvm/src/back/profiling.rs:53
fn before_pass_callback(&'a mut self, pass_name: &str, ir_name: &str) {
let event_id = llvm_args_to_string_id(&self.profiler, pass_name, ir_name);
self.stack.push(TimingGuard::start(&self.profiler, self.llvm_pass_event_kind, event_id));
}
fn after_pass_callback(&mut self) {
self.stack.pop();
}
}
pub(crate) unsafe extern "C" fn selfprofile_before_pass_callback(
llvm_self_profiler: *mut c_void,
pass_name: *const c_char,
ir_name: *const c_char,
) {
unsafe {
let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8");
let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8");
llvm_self_profiler.before_pass_callback(pass_name, ir_name);
}
}
pub(crate) unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };
llvm_self_profiler.after_pass_callback();
}
View on GitHub (pinned to 22057b88b0)
Solutions
- Use the official rustup toolchain instead of a custom-built rustc+LLVM to rule out an ABI/name mismatch.
- If using a custom LLVM, audit any out-of-tree or patched passes for non-ASCII/uninitialized pass-name strings passed to the callback registration.
- Temporarily disable self-profiling (`-Z self-profile=` unset) to confirm the crash is profiling-callback-specific.
- Rebuild the rustc/LLVM toolchain cleanly (clobber) to eliminate stale-object ABI drift.
- Report to the rustc team with the LLVM revision and pass name bytes if reproducible on stock toolchain.
Example fix
# before: self-profile triggers FFI UTF-8 panic on custom LLVM RUSTFLAGS='-Z self-profile=/tmp/profile' cargo build # after: drop self-profile and/or switch to stock toolchain # 1) stop profiling cargo build # 2) or use official toolchain rustup default stable
Defensive patterns
Strategy: try-catch
Try / catch
let res = std::panic::catch_unwind(|| {
// path that enables -Zself-profile (LLVM pass-name callback)
run_codegen_with_self_profile()
});
if res.is_err() {
// LLVM emitted a non-UTF-8 pass name; disable self-profile and retry.
run_codegen_without_self_profile();
} Prevention
- Use the LLVM version bundled with your rustc toolchain; mismatched LLVM may emit non-UTF-8 pass names.
- Do not load custom LLVM plugins whose registered pass names contain non-UTF-8 bytes.
- Disable -Zself-profile unless you need it; the panic only fires on the pass-name callback.
- Report to rustc if it reproduces with stock toolchain - this is an internal invariant violation.
When it happens
Trigger: Triggered when the compiler is built/run with self-profiling enabled AND LLVM invokes the registered `selfprofile_before_pass_callback` with a `pass_name` pointer whose bytes are not valid UTF-8 (e.g. uninitialized pointer, mis-registered pass name from a custom/out-of-tree LLVM pass, or a corrupted LLVM C-string).
Common situations: Using a custom or patched LLVM with a pass that registers a non-UTF-8/garbage name; an LLVM/rustc ABI mismatch after a botched toolchain build; memory corruption from a faulty LLVM plugin; rare when using the official rustup toolchain. Almost never seen with stock LLVM.
Related errors
- non-UTF8 diagnostic
- not implemented
- got a non-UTF8 data-layout from LLVM
- unsupported integer: {self:?}
- unsupported float: {self:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/dda35a47a2badde8.json.
Report an issue: GitHub.