{"record":{"id":"fdcdc85522bb9d31","repo":"firecracker-microvm/firecracker","slug":"poisoned-lock-fdcdc8","errorCode":null,"errorMessage":"poisoned lock","messagePattern":"poisoned lock","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/vmm/src/logger/metrics.rs","lineNumber":153,"sourceCode":"    /// Upon success, the function will return `True` (if metrics system was initialized and metrics\n    /// were successfully written to disk) or `False` (if metrics system was not yet initialized).\n    ///\n    /// This function is usually supposed to be called only from a single thread and\n    /// is not meant to be used in a multithreaded scenario. The reason\n    /// `metrics_buf` is enclosed in a `Mutex` is that `lazy_static` enforces\n    /// thread-safety on all its members.\n    /// The only exception is for signal handlers that result in process exit, which may be run on\n    /// any thread. To prevent the race condition present in the serialisation step of\n    /// SharedIncMetrics, deadly signals use SharedStoreMetrics instead (which have a thread-safe\n    /// serialise implementation).\n    /// The only known caveat is that other metrics may not be properly written before exiting from\n    /// a signal handler. We make this compromise since the process will be killed anyway and the\n    /// important metric in this case is the signal one.\n    /// The alternative is to hold a Mutex over the entire function call, but this increases the\n    /// known deadlock potential.\n    pub fn write(&self) -> Result<bool, MetricsError> {\n        if let Some(lock) = self.metrics_buf.get() {\n            let mut writer = lock.lock().expect(\"poisoned lock\");\n            serde_json::to_writer(writer.by_ref(), &self.app_metrics)\n                .map_err(|err| MetricsError::Serde(err.to_string()))?;\n            writer.write_all(b\"\\n\").map_err(MetricsError::Write)?;\n            Ok(true)\n        } else {\n            // If the metrics are not initialized, no error is thrown but we do let the user know\n            // that metrics were not written.\n            Ok(false)\n        }\n    }\n}\n\nimpl<T: Serialize + Debug, M: Write + Send + Debug> Deref for Metrics<T, M> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.app_metrics\n    }","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/firecracker-microvm/firecracker/blob/0a745def42ddf4cc2a744d79a08a27ff50b5d27a/src/vmm/src/logger/metrics.rs#L135-L171","documentation":"Error \"poisoned lock\" thrown in firecracker-microvm/firecracker.","triggerScenarios":"Thrown at src/vmm/src/logger/metrics.rs:153 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Find and fix the earlier panic that poisoned the metrics lock.","Recover with into_inner() only if the metrics state is provably consistent after the panic."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0a745def42ddf4cc2a744d79a08a27ff50b5d27a","analyzedAt":"2026-08-19T05:27:02.517Z","contentChangedAt":"2026-08-19T05:27:02.517Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}