{"record":{"id":"a52a0867fd2bfb1b","repo":"rust-lang/rust-analyzer","slug":"profiler-is-not-started","errorCode":null,"errorMessage":"profiler is not started","messagePattern":"profiler is not started","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/profile/src/google_cpu_profiler.rs","lineNumber":40,"sourceCode":"    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":22,"sourceCodeEnd":45,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/profile/src/google_cpu_profiler.rs#L22-L45","documentation":"`stop` transitions the profiler state ON -> PENDING before calling `ProfilerStop`. If the profiler is not currently running (state is not ON), the transition fails and `stop` panics with 'profiler is not started', protecting against stopping a non-existent profile session.","triggerScenarios":"Calling `profile::stop()` without a prior successful `start()`; calling `stop()` twice; calling `stop()` while a `start()` is still initializing (PENDING state).","commonSituations":"Cleanup/shutdown code that unconditionally calls stop; a previous start that panicked left nothing to stop; lifecycle bugs where stop runs in a destructor after state was already reset.","solutions":["Only call `stop()` after a confirmed successful `start()`","Track profiling state in your own code (bool/guard) and make stop idempotent","Fix duplicated cleanup paths that invoke stop more than once"],"exampleFix":"// before\nprofiler::stop(); // unconditional, may panic\n// after\nif profiling {\n    profiler::stop();\n    profiling = false;\n}","handlingStrategy":"try-catch","validationCode":"static PROFILING: AtomicBool = AtomicBool::new(false);\nfn can_stop() -> bool { PROFILING.load(Ordering::SeqCst) }","typeGuard":null,"tryCatchPattern":"std::panic::catch_unwind(|| profiler::stop())\n    .err()\n    .map(|_| eprintln!(\"profiler was not running; ignoring stop\"));","preventionTips":["Track profiling state yourself and only stop when a start succeeded","Make shutdown/cleanup paths idempotent with respect to stop()","Never call stop() from destructors that may run after state reset","Guard start/stop pairs in a single RAII type"],"tags":["rust","profiling","state-machine","panic"],"backgroundTag":"profiler-not-running","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"}