diff --git a/e2e-tests/tests/script_execution.rs b/e2e-tests/tests/script_execution.rs index aec9b24b..0d305344 100644 --- a/e2e-tests/tests/script_execution.rs +++ b/e2e-tests/tests/script_execution.rs @@ -10,6 +10,36 @@ mod common; +#[tokio::test] +async fn test_partial_compilation_failures_are_visible_without_logging() -> anyhow::Result<()> { + init(); + let target = common::targets::TargetLauncher::sample_program_with_opt(OptimizationLevel::Debug) + .spawn() + .await?; + let (code, stdout, stderr) = common::runner::GhostscopeRunner::new() + .with_script( + r#" +trace process_record { print "PARTIAL_GOOD"; } +trace no_such_partial_failure_target { print "PARTIAL_BAD"; } +"#, + ) + .attach_to(&target) + .with_cli_args(["--no-log", "--no-status"]) + .timeout_secs(3) + .run() + .await?; + target.terminate().await?; + assert_eq!(code, 0, "stderr={stderr} stdout={stdout}"); + assert!(stdout.contains("PARTIAL_GOOD"), "{stdout}"); + assert!(!stdout.contains("PARTIAL_BAD"), "{stdout}"); + assert!( + stderr.contains("no_such_partial_failure_target"), + "{stderr}" + ); + assert!(stderr.contains("failed to compile"), "{stderr}"); + Ok(()) +} + use common::{init, OptimizationLevel, FIXTURES}; use lazy_static::lazy_static; use std::collections::HashMap; diff --git a/ghostscope/src/script/cli.rs b/ghostscope/src/script/cli.rs index 8a4e40d1..21b2e026 100644 --- a/ghostscope/src/script/cli.rs +++ b/ghostscope/src/script/cli.rs @@ -45,6 +45,21 @@ pub fn compile_script_for_cli( failed.target_name, failed.pc_address, failed.error_message ); } + // Partial success still produces a runnable script. These diagnostics + // must remain visible when script mode disables logging and status UI. + if !compilation_result.uprobe_configs.is_empty() { + eprintln!( + "Warning: {} trace target(s) failed to compile; {} probe(s) compiled successfully:", + compilation_result.failed_targets.len(), + compilation_result.uprobe_configs.len() + ); + for failed in &compilation_result.failed_targets { + eprintln!( + " {} at 0x{:x}: {}", + failed.target_name, failed.pc_address, failed.error_message + ); + } + } } Ok(compilation_result)