{"record":{"id":"31be6ad582dc565b","repo":"rust-lang/rust-analyzer","slug":"profiler-failed-to-start","errorCode":null,"errorMessage":"profiler failed to start","messagePattern":"profiler failed to start","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/profile/src/google_cpu_profiler.rs","lineNumber":33,"sourceCode":"}\n\nconst OFF: usize = 0;\nconst ON: usize = 1;\nconst PENDING: usize = 2;\n\nfn transition(current: usize, new: usize) -> bool {\n    static STATE: AtomicUsize = AtomicUsize::new(OFF);\n\n    STATE.compare_exchange(current, new, Ordering::SeqCst, Ordering::SeqCst).is_ok()\n}\n\npub(crate) fn start(path: &Path) {\n    if !transition(OFF, PENDING) {\n        panic!(\"profiler already started\");\n    }\n    let path = CString::new(path.display().to_string()).unwrap();\n    if unsafe { ProfilerStart(path.as_ptr()) } == 0 {\n        panic!(\"profiler failed to start\")\n    }\n    assert!(transition(PENDING, ON));\n}\n\npub(crate) fn stop() {\n    if !transition(ON, PENDING) {\n        panic!(\"profiler is not started\")\n    }\n    unsafe { ProfilerStop() };\n    assert!(transition(PENDING, OFF));\n}\n","sourceCodeStart":15,"sourceCodeEnd":45,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/profile/src/google_cpu_profiler.rs#L15-L45","documentation":"After atomically transitioning OFF -> PENDING, `start` invokes the gperftools `ProfilerStart` C function. If it returns 0 the native profiler failed to begin recording, and the wrapper panics with 'profiler failed to start'.","triggerScenarios":"`ProfilerStart(path)` returning 0, typically because the output file at `path` cannot be created/written (bad directory, permissions, invalid path bytes).","commonSituations":"Passing a profile output path in a non-existent or read-only directory; running in a sandboxed/containerized environment without write access; path containing interior NUL would instead hit the CString unwrap earlier.","solutions":["Verify the output directory exists and is writable before calling start","Check the path for invalid characters and that the filesystem has space","Wrap profiler startup in a check and fall back to running unprofiled if the environment disallows it"],"exampleFix":"// before\nprofiler::start(&Path::new(\"/proc/1/cpu.prof\"));\n// after\nlet path = Path::new(\"/tmp/cpu.prof\");\nif path.parent().map_or(false, |d| d.is_dir()) {\n    profiler::start(path);\n}","handlingStrategy":"validation","validationCode":"fn profiler_output_ok(path: &Path) -> bool {\n    path.parent().map_or(false, |d| d.is_dir())\n        && path.extension().is_some()\n}","typeGuard":null,"tryCatchPattern":"std::panic::catch_unwind(|| profiler::start(path))\n    .err()\n    .map(|_| eprintln!(\"profiling unavailable; continuing unprofiled\"));","preventionTips":["Ensure the profile output directory exists and is writable before starting","Test profiler startup in your deployment sandbox/container","Validate the path (no interior NULs, valid filesystem) before calling start","Treat profiling as optional: fail soft when the native profiler refuses to start"],"tags":["rust","profiling","filesystem","gperftools","panic"],"backgroundTag":"profiler-start-failure","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}