{"id":"dda35a47a2badde8","repo":"rust-lang/rust","slug":"valid-utf-8","errorCode":null,"errorMessage":"valid UTF-8","messagePattern":"valid UTF-8","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_llvm/src/back/profiling.rs","lineNumber":53,"sourceCode":"\n    fn before_pass_callback(&'a mut self, pass_name: &str, ir_name: &str) {\n        let event_id = llvm_args_to_string_id(&self.profiler, pass_name, ir_name);\n\n        self.stack.push(TimingGuard::start(&self.profiler, self.llvm_pass_event_kind, event_id));\n    }\n    fn after_pass_callback(&mut self) {\n        self.stack.pop();\n    }\n}\n\npub(crate) unsafe extern \"C\" fn selfprofile_before_pass_callback(\n    llvm_self_profiler: *mut c_void,\n    pass_name: *const c_char,\n    ir_name: *const c_char,\n) {\n    unsafe {\n        let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);\n        let pass_name = CStr::from_ptr(pass_name).to_str().expect(\"valid UTF-8\");\n        let ir_name = CStr::from_ptr(ir_name).to_str().expect(\"valid UTF-8\");\n        llvm_self_profiler.before_pass_callback(pass_name, ir_name);\n    }\n}\n\npub(crate) unsafe extern \"C\" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {\n    let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };\n    llvm_self_profiler.after_pass_callback();\n}\n","sourceCodeStart":35,"sourceCodeEnd":63,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_llvm/src/back/profiling.rs#L35-L63","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"# before: self-profile triggers FFI UTF-8 panic on custom LLVM\nRUSTFLAGS='-Z self-profile=/tmp/profile' cargo build\n\n# after: drop self-profile and/or switch to stock toolchain\n# 1) stop profiling\ncargo build\n# 2) or use official toolchain\nrustup default stable","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let res = std::panic::catch_unwind(|| {\n    // path that enables -Zself-profile (LLVM pass-name callback)\n    run_codegen_with_self_profile()\n});\nif res.is_err() {\n    // LLVM emitted a non-UTF-8 pass name; disable self-profile and retry.\n    run_codegen_without_self_profile();\n}","preventionTips":["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."],"tags":["rustc","self-profile","llvm","ffi","utf8"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}