use crate::config::MergedConfig;
use crate::core::GhostSession;
use anyhow::Result;
use ghostscope_dwarf::ModuleLoadingEvent;
use ghostscope_ui::{events::ModuleLoadingStats as UIModuleLoadingStats, RuntimeStatus};
use tracing::info;
fn convert_loading_event_to_runtime_status(event: ModuleLoadingEvent) -> RuntimeStatus {
match event {
ModuleLoadingEvent::Discovered {
module_path,
current: _,
total,
} => RuntimeStatus::DwarfModuleDiscovered {
module_path,
total_modules: total,
},
ModuleLoadingEvent::LoadingStarted {
module_path,
current,
total,
} => RuntimeStatus::DwarfModuleLoadingStarted {
module_path,
current,
total,
},
ModuleLoadingEvent::LoadingCompleted {
module_path,
stats,
current,
total,
} => {
let ui_stats = UIModuleLoadingStats {
functions: stats.functions,
variables: stats.variables,
types: stats.types,
load_time_ms: stats.load_time_ms,
};
RuntimeStatus::DwarfModuleLoadingCompleted {
module_path,
stats: ui_stats,
current,
total,
}
}
ModuleLoadingEvent::LoadingFailed {
module_path,
error,
current,
total,
} => RuntimeStatus::DwarfModuleLoadingFailed {
module_path,
error,
current,
total,
},
}
}
pub async fn initialize_dwarf_processing(
config: &MergedConfig,
status_sender: tokio::sync::mpsc::UnboundedSender<RuntimeStatus>,
) -> Result<GhostSession> {
initialize_dwarf_processing_with_progress(config, status_sender).await
}
pub async fn initialize_dwarf_processing_with_progress(
config: &MergedConfig,
status_sender: tokio::sync::mpsc::UnboundedSender<RuntimeStatus>,
) -> Result<GhostSession> {
let _ = status_sender.send(RuntimeStatus::DwarfLoadingStarted);
let progress_callback = {
let sender = status_sender.clone();
move |event: ModuleLoadingEvent| {
let runtime_status = convert_loading_event_to_runtime_status(event);
let _ = sender.send(runtime_status);
}
};
match GhostSession::new_with_config_and_progress(config, progress_callback).await {
Ok(session) => {
match session.get_module_stats() {
Some(stats) => {
info!("✓ Process analysis successful in TUI mode");
info!(" Total modules: {}", stats.total_modules);
info!(" Executable modules: {}", stats.executable_modules);
info!(" Library modules: {}", stats.library_modules);
info!(" Total symbols: {}", stats.total_symbols);
info!(
" Modules with debug info: {}",
stats.modules_with_debug_info
);
let functions = session.list_functions();
let symbols_count = functions.len();
if stats.modules_with_debug_info == 0 {
let _ = status_sender.send(RuntimeStatus::DwarfLoadingFailed(
"No debug information available. Compile with -g for full functionality"
.to_string(),
));
} else {
let _ = status_sender
.send(RuntimeStatus::DwarfLoadingCompleted { symbols_count });
}
Ok(session)
}
None => {
let error_msg = format!(
"Binary analysis failed! Cannot load DWARF information for PID {} or binary path {:?}",
config.pid.unwrap_or(0),
config.binary_path
);
let _ =
status_sender.send(RuntimeStatus::DwarfLoadingFailed(error_msg.clone()));
Err(anyhow::anyhow!(error_msg))
}
}
}
Err(e) => {
let error_msg = format!("Failed to create debug session: {e}");
let _ = status_sender.send(RuntimeStatus::DwarfLoadingFailed(error_msg.clone()));
Err(anyhow::anyhow!(error_msg))
}
}
}