Skip to content
2 changes: 1 addition & 1 deletion docs/tui-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ After pressing `Ctrl+R`:

| Shortcut | Function |
|----------|----------|
| `Esc` or `jk` | Enter Command Mode (jk must be pressed within 100ms) |
| `Esc` or `jk` | Enter Command Mode (jk must be pressed within 150ms) |

### Mode: Command Mode

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/tui-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ GhostScope TUI 界面由三个面板组成,每个面板具有不同的功能

| 快捷键 | 功能 |
|--------|------|
| `Esc` 或 `jk` | 进入命令模式(jk 需在 100ms 内按下)|
| `Esc` 或 `jk` | 进入命令模式(jk 需在 150ms 内按下)|

### 模式:命令模式

Expand Down
2 changes: 1 addition & 1 deletion ghostscope-compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub enum CompileError {
#[error("LLVM error: {0}")]
LLVM(String),

#[error("Error: {0}")]
#[error("{0}")]
Other(String),
}

Expand Down
67 changes: 52 additions & 15 deletions ghostscope-compiler/src/script/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl<'a> AstCompiler<'a> {
// Continue processing even if some trace points fail
let mut successful_trace_points = 0;
let mut failed_trace_points = 0;
let mut first_error: Option<String> = None;

for (index, stmt) in program.statements.iter().enumerate() {
match stmt {
Expand All @@ -128,11 +129,46 @@ impl<'a> AstCompiler<'a> {
}
Err(e) => {
failed_trace_points += 1;
let error_msg = e.to_string();
error!(
"❌ Failed to process trace point {}: {:?} - Error: {}",
index, pattern, e
index, pattern, error_msg
);
// Continue processing other trace points

// Save first error for detailed error message
if first_error.is_none() {
first_error = Some(error_msg.clone());
}

// Check if failed_targets was already populated by process_trace_point
// (e.g., when all addresses failed for a function)
// If not, add a general failed target entry
let has_failed_for_this_pattern =
self.failed_targets.iter().any(|ft| match pattern {
TracePattern::FunctionName(name) => ft.target_name == *name,
TracePattern::SourceLine {
file_path,
line_number,
} => ft.target_name == format!("{}:{}", file_path, line_number),
_ => false,
});

if !has_failed_for_this_pattern {
let target_name = match pattern {
TracePattern::FunctionName(name) => name.clone(),
TracePattern::SourceLine {
file_path,
line_number,
} => format!("{}:{}", file_path, line_number),
_ => format!("trace_point_{}", index),
};

self.failed_targets.push(FailedTarget {
target_name,
pc_address: 0,
error_message: error_msg,
});
}
}
}
}
Expand All @@ -153,12 +189,12 @@ impl<'a> AstCompiler<'a> {
"Partial success: {} trace points successful, {} failed",
successful_trace_points, failed_trace_points
);
} else {
} else if failed_trace_points > 0 {
// All trace points failed - return error with first failure reason
error!("All {} trace points failed to process", failed_trace_points);
return Err(CompileError::Other(format!(
"All {} trace points failed to process",
failed_trace_points
)));
return Err(CompileError::Other(
first_error.unwrap_or_else(|| "All trace points failed".to_string()),
));
}

// Generate target info summary
Expand Down Expand Up @@ -291,11 +327,11 @@ impl<'a> AstCompiler<'a> {
};

if module_addresses.is_empty() {
warn!(
"No addresses resolved for function '{}'; skipping",
// Strict behavior: fail this trace point immediately instead of skipping silently
return Err(CompileError::Other(format!(
"No addresses resolved for function '{}' - function not found in debug symbols",
func_name
);
return Ok(());
)));
}

let total_addresses: usize = module_addresses.len();
Expand Down Expand Up @@ -359,19 +395,20 @@ impl<'a> AstCompiler<'a> {
"All {} addresses for function '{}' processed successfully",
successful_addresses, func_name
);
Ok(())
} else if successful_addresses > 0 && failed_addresses > 0 {
warn!(
"Partial success for function '{}': {} successful, {} failed addresses",
func_name, successful_addresses, failed_addresses
);
Ok(())
} else {
error!(
// All addresses failed to process - this is an error
Err(CompileError::Other(format!(
"All {} addresses for function '{}' failed to process",
failed_addresses, func_name
);
// Don't return error here - let the caller decide based on overall results
)))
}
Ok(())
}
_ => {
unimplemented!();
Expand Down
Loading