diff --git a/server/src/crash_buffer.rs b/server/src/crash_buffer.rs new file mode 100644 index 00000000..6359edb0 --- /dev/null +++ b/server/src/crash_buffer.rs @@ -0,0 +1,29 @@ + +use lsp_server::Message; +use std::collections::VecDeque; +use std::sync::Mutex; +use std::sync::OnceLock; + +const N: usize = 20; + +pub static CRASH_BUFFER: OnceLock>> = OnceLock::new(); + +pub fn init_crash_buffer() { + let _ = CRASH_BUFFER.set(Mutex::new(VecDeque::with_capacity(N))); +} + +pub fn push_message(msg: Message) { + if let Some(buffer) = CRASH_BUFFER.get() { + let mut buf = buffer.lock().unwrap(); + if buf.len() == N { buf.pop_front(); } + buf.push_back(msg); + } +} + +pub fn get_messages() -> Vec { + if let Some(buffer) = CRASH_BUFFER.get() { + buffer.lock().unwrap().iter().cloned().collect() + } else { + Vec::new() + } +} diff --git a/server/src/lib.rs b/server/src/lib.rs index 0b7ef237..959a3044 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -7,4 +7,5 @@ pub mod threads; pub mod features; pub mod server; pub mod tasks; -pub mod utils; \ No newline at end of file +pub mod utils; +pub mod crash_buffer; \ No newline at end of file diff --git a/server/src/main.rs b/server/src/main.rs index d46407d6..cbc8bc27 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,6 +1,6 @@ use lsp_server::Notification; use serde_json::json; -use odoo_ls_server::{args::{Cli, LogLevel}, cli_backend::CliBackend, constants::*, server::Server, utils::PathSanitizer}; +use odoo_ls_server::{args::{Cli, LogLevel}, cli_backend::CliBackend, constants::*, server::Server, utils::PathSanitizer, crash_buffer}; use clap::Parser; use tracing::{info, Level}; use tracing_appender::rolling::{RollingFileAppender, Rotation}; @@ -17,6 +17,7 @@ static GLOBAL: TrackingAllocator = TrackingAllocator; fn main() { // TODO: Audit that the environment access only happens in single-threaded code. unsafe { env::set_var("RUST_BACKTRACE", "full") }; + crash_buffer::init_crash_buffer(); let cli = Cli::parse(); let use_debug = cli.use_tcp; @@ -99,10 +100,13 @@ fn main() { std::panic::set_hook(Box::new(move |panic_info| { let backtrace = std::backtrace::Backtrace::capture(); panic_hook(panic_info); + let recent_msgs = crash_buffer::get_messages(); + let recent_msgs_json = serde_json::to_string_pretty(&recent_msgs).unwrap_or_default(); let _ = sender_panic.send(lsp_server::Message::Notification(Notification{ method: "Odoo/displayCrashNotification".to_string(), params: json!({ "crashInfo": format!("{panic_info}\n\nTraceback:\n{backtrace}"), + "recentMessages": recent_msgs_json, "pid": std::process::id() }) })); diff --git a/server/src/server.rs b/server/src/server.rs index 2e48b75a..2736ab4c 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -9,7 +9,7 @@ use serde_json::json; use nix; use tracing::{error, info, warn}; -use crate::{constants::{DEBUG_THREADS, EXTENSION_VERSION}, core::{file_mgr::FileMgr, odoo::SyncOdoo}, threads::{delayed_changes_process_thread, message_processor_thread_main, DelayedProcessingMessage}, S}; +use crate::{constants::{DEBUG_THREADS, EXTENSION_VERSION}, core::{file_mgr::FileMgr, odoo::SyncOdoo}, threads::{delayed_changes_process_thread, message_processor_thread_main, DelayedProcessingMessage}, S, crash_buffer}; /** @@ -293,6 +293,13 @@ impl Server { } if index == 0 { //comes from client + // Save Requests and Notifications to crash buffer + match &msg { + Message::Request(_) | Message::Notification(_) => { + crash_buffer::push_message(msg.clone()); + }, + _ => {} + } if let Message::Request(r) = &msg { if r.method == "shutdown" { let resp = lsp_server::Response::new_ok(r.id.clone(), ());