Project for the System Programming Course, regarding a fault injection environment for redundant application/
- Introduction
- Project Overview
- Code Transformation for Fault Tolerance
- Fault Injection Environment
- Usage
- Project Structure
- Results and Analysis
- Future Improvements
- Authors
Fault tolerance is a critical aspect of safety-critical applications. Traditional reliability metrics such as MTBF (Mean Time Between Failures) require long observation periods, making it difficult to assess system dependability efficiently. This project introduces a software-based fault injection environment to evaluate the robustness of redundant applications using the Rust programming language.
The project aims to:
- Implement a fault-tolerant application by systematically modifying Rust source code to introduce redundancy.
- Develop a fault injection environment to test the effectiveness of these transformations by simulating faults.
This approach is based on the single bit-flip fault model, commonly used in software fault injection research.
To introduce redundancy into the application, the following transformations are applied:
- Rule #1: Each variable
x
is duplicated intocp1
andcp2
. - Rule #2: All write operations are performed on both copies.
- Rule #3: Before any read operation, the consistency between
cp1
andcp2
is checked. If a mismatch is found, an error is raised.
This logic is encapsulated in a custom Rust generic type Hardened<T>
, which includes various traits to support arithmetic operations, comparisons, and error handling.
The fault injection system follows a Pipes and Filters architecture, consisting of:
- Fault List Manager (FLM): Generates a fault list containing variable names, injection times, and flipped bits.
- Injector (FIM): Introduces faults in the application during execution.
- Analyzer: Collects execution data, detects errors, and categorizes them into silent and detected faults.
The system supports concurrent execution using multi-threading with Rust’s mpsc
(multiple producer, single consumer) channels for inter-component communication.
- Rust compiler
- Cargo package manager
# Clone the repository
git clone <repository-url>
cd <project-directory>
# Build and run the fault-tolerant application
cargo run --release
# Execute the fault injection environment
cargo run --bin fault_injector
# Analyze results
cat results/report.json
├── src/
│ ├── hardened.rs # Implementation of Hardened<T>
│ ├── fault_list.rs # Fault List Manager
│ ├── injector.rs # Fault Injector
│ ├── analyzer.rs # Result Analyzer
│ ├── main.rs # Entry point
├── data/
│ ├── dataset.txt # Predefined datasets
│ ├── input.txt # User-defined inputs
├── results/
│ ├── report.json # Experiment results
├── Cargo.toml # Rust dependencies and project metadata
└── README.md # Project documentation
- The fault injection experiments were conducted on three algorithms:
- Selection Sort
- Bubble Sort
- Matrix Multiplication
- The analysis categorized faults as:
- Silent Faults: Undetected faults that did not affect output.
- Detected Faults: Errors identified by the system.
- Fatal Faults: Errors leading to incorrect results.
Total Faults Injected: 2000
Detected Faults: 1490 (74.5%)
Silent Faults: 510 (25.5%)
Fatal Faults: 251 (12.55%)
- Optimization of fault list generation to reduce redundant fault injections.
- Expansion of fault models beyond single bit-flip faults.
- Integration with machine learning for predictive fault analysis.
- Carlo Migliaccio
- Federico Pretini
- Alessandro Scavone
- Mattia Viglino
Project developed at Politecnico di Torino for the Programmazione di Sistema course (2024/25).