Skip to content

Commit

Permalink
fix: don't hang if tracer crashed
Browse files Browse the repository at this point in the history
  • Loading branch information
kxxt committed Aug 6, 2024
1 parent 9121977 commit ed36cea
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub enum Event {
pub enum TracerMessage {
Event(TracerEvent),
StateUpdate(ProcessStateUpdateEvent),
FatalError(String),
}

impl From<TracerEvent> for TracerMessage {
Expand Down
36 changes: 28 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,22 @@ async fn main() -> color_eyre::Result<()> {
)?);
let tracer_thread = tracer.spawn(cmd, Some(output), req_rx);
loop {
if let Some(TracerMessage::Event(TracerEvent {
details: TracerEventDetails::TraceeExit { exit_code, .. },
..
})) = tracer_rx.recv().await
{
tracing::debug!("Waiting for tracer thread to exit");
tracer_thread.await??;
process::exit(exit_code);
match tracer_rx.recv().await {
Some(TracerMessage::Event(TracerEvent {
details: TracerEventDetails::TraceeExit { exit_code, .. },
..
})) => {
tracing::debug!("Waiting for tracer thread to exit");
tracer_thread.await??;
process::exit(exit_code);
}
// channel closed abnormally.
None | Some(TracerMessage::FatalError(_)) => {
tracing::debug!("Waiting for tracer thread to exit");
tracer_thread.await??;
process::exit(1);
}
_ => (),
}
}
}
Expand Down Expand Up @@ -282,6 +290,12 @@ async fn main() -> color_eyre::Result<()> {
})) => {
json.events.push(JsonExecEvent::new(id, *exec));
}
// channel closed abnormally.
None | Some(TracerMessage::FatalError(_)) => {
tracing::debug!("Waiting for tracer thread to exit");
tracer_thread.await??;
process::exit(1);
}
_ => (),
}
}
Expand All @@ -307,6 +321,12 @@ async fn main() -> color_eyre::Result<()> {
output.write_all(&[b'\n'])?;
output.flush()?;
}
// channel closed abnormally.
None | Some(TracerMessage::FatalError(_)) => {
tracing::debug!("Waiting for tracer thread to exit");
tracer_thread.await??;
process::exit(1);
}
_ => (),
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,15 @@ impl Tracer {
let current_thread = pthread_self();
pthread_setname_np(current_thread, "tracer\0\0\0\0\0\0\0\0\0\0".as_ptr().cast());
}
tokio::runtime::Handle::current().block_on(async move {
let tx = self.msg_tx.clone();
let result = tokio::runtime::Handle::current().block_on(async move {
self.printer.init_thread_local(output);
self.run(args, req_rx).await
})
});
if let Err(e) = &result {
tx.send(TracerMessage::FatalError(e.to_string())).unwrap();
}
result
}
})
}
Expand Down
59 changes: 34 additions & 25 deletions src/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use tokio::{
use tokio_util::sync::CancellationToken;
use tracing::{error, trace};

use crate::event::{Event, TracerMessage};
use crate::event::{Event, TracerEvent, TracerEventDetails, TracerEventMessage, TracerMessage};

pub mod app;
mod breakpoint_manager;
Expand Down Expand Up @@ -112,33 +112,42 @@ impl Tui {
let crossterm_event = reader.next().fuse();
let tracer_event = tracer_rx.recv();
tokio::select! {
_ = _cancellation_token.cancelled() => {
break;
}
Some(tracer_event) = tracer_event => {
trace!("TUI event: tracer message!");
_ = _cancellation_token.cancelled() => {
break;
}
tracer_event = tracer_event => {
trace!("TUI event: tracer message!");
if let Some(tracer_event) = tracer_event {
_event_tx.send(Event::Tracer(tracer_event)).unwrap();
} else {
// channel closed abnormally
_event_tx.send(Event::Tracer(TracerMessage::Event(TracerEvent {
details: TracerEventDetails::Error(TracerEventMessage {
pid: None,
msg: "The connection between TUI and tracer shutdown abnormally. Tracer is probably died.".to_string()
}), id: u64::MAX }))).unwrap();
}
Some(event) = crossterm_event => {
#[cfg(debug_assertions)]
trace!("TUI event: crossterm event {event:?}!");
match event {
Ok(evt) => {
match evt {
CrosstermEvent::Key(key) => {
if key.kind == KeyEventKind::Press {
_event_tx.send(Event::Key(key)).unwrap();
}
},
CrosstermEvent::Resize(cols, rows) => {
_event_tx.send(Event::Resize(Size {
width: cols,
height: rows,
})).unwrap();
},
_ => {},
}
}
Some(event) = crossterm_event => {
#[cfg(debug_assertions)]
trace!("TUI event: crossterm event {event:?}!");
match event {
Ok(evt) => {
match evt {
CrosstermEvent::Key(key) => {
if key.kind == KeyEventKind::Press {
_event_tx.send(Event::Key(key)).unwrap();
}
},
CrosstermEvent::Resize(cols, rows) => {
_event_tx.send(Event::Resize(Size {
width: cols,
height: rows,
})).unwrap();
},
_ => {},
}
}
Err(_) => {
_event_tx.send(Event::Error).unwrap();
}
Expand Down
11 changes: 11 additions & 0 deletions src/tui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,17 @@ impl App {
self.event_list.update(update);
}
}
TracerMessage::FatalError(e) => {
action_tx.send(Action::SetActivePopup(ActivePopup::InfoPopup(
InfoPopupState::error(
"FATAL ERROR in tracer thread".to_string(),
vec![
Line::raw("The tracer thread has died abnormally! error: "),
e.into(),
],
),
)))?;
}
}
// action_tx.send(Action::Render)?;
}
Expand Down

0 comments on commit ed36cea

Please sign in to comment.