borrowscope-runtime 0.1.2

Runtime tracking system for BorrowScope
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# BorrowScope Runtime

A comprehensive runtime tracking library for visualizing Rust's ownership and borrowing system. BorrowScope Runtime captures ownership transfers, borrows, smart pointer operations, and unsafe code patterns as they happen, generating structured event data for analysis and visualization.

## Why BorrowScope Runtime?

Rust's ownership system operates at compile time, making it invisible during execution. BorrowScope Runtime bridges this gap by instrumenting your code to capture every ownership operation at runtime. Whether you're learning Rust, debugging complex ownership issues, or analyzing memory patterns, this library makes the invisible mechanics of Rust's memory model visible.

## Features

- **Comprehensive Coverage**: 41+ tracking functions covering all Rust ownership patterns
- **Zero-Cost Abstraction**: Complete compile-time elimination when `track` feature is disabled
- **Thread Safety**: All operations are thread-safe with efficient synchronization
- **RAII Guards**: Automatic drop tracking with guard types
- **Event Sourcing**: Store events and build ownership graphs on demand
- **Rich Analysis**: Lifetime analysis, timeline construction, and graph statistics
- **JSON Export**: Export tracking data for visualization tools
- **Performance**: ~75-80ns per tracking call, ~80 bytes per event

## Quick Start

Add to your `Cargo.toml`:

```toml
[dependencies]
borrowscope-runtime = { version = "0.1", features = ["track"] }
```

Basic usage:

```rust
use borrowscope_runtime::*;

fn main() {
    reset(); // Clear any previous tracking data
    
    // Track variable creation
    let data = track_new("data", vec![1, 2, 3]);
    
    // Track borrowing
    let r1 = track_borrow("r1", &data);
    let r2 = track_borrow("r2", &data);
    println!("Borrowed: {:?}, {:?}", r1, r2);
    
    // Track drops
    track_drop("r2");
    track_drop("r1");
    track_drop("data");
    
    // Export events as JSON
    let events = get_events();
    println!("{}", serde_json::to_string_pretty(&events).unwrap());
    
    // Build ownership graph
    let graph = get_graph();
    println!("Graph: {} variables, {} relationships", 
             graph.nodes.len(), graph.edges.len());
}
```

## Comprehensive API

### Basic Ownership Tracking

Track fundamental ownership operations:

```rust
// Variable creation and destruction
let x = track_new("x", 42);                    // Track variable creation
let y = track_move("y", x);                    // Track ownership transfer
track_drop("y");                               // Track variable drop

// Borrowing operations
let data = track_new("data", vec![1, 2, 3]);
let r = track_borrow("r", &data);              // Track immutable borrow
let r_mut = track_borrow_mut("r_mut", &mut data); // Track mutable borrow
```

### RAII Guards (Automatic Drop Tracking)

Eliminate manual drop tracking with RAII guards:

```rust
{
    let data = track_new_guard("data", vec![1, 2, 3]);
    let r = track_borrow_guard("r", &*data);
    let r_mut = track_borrow_mut_guard("r_mut", &mut *data);
    // track_drop called automatically when guards go out of scope
}

// Guards support transparent access via Deref/DerefMut
let guard = track_new_guard("x", 42);
println!("{}", *guard); // Access inner value
```

### Smart Pointer Tracking

Track reference-counted smart pointers with precise count monitoring:

```rust
use std::rc::Rc;
use std::sync::Arc;

// Rc<T> tracking
let rc1 = track_rc_new("rc1", Rc::new(42));
let rc2 = track_rc_clone("rc2", "rc1", rc1.clone());
// Automatically tracks strong_count and weak_count

// Arc<T> tracking (thread-safe)
let arc1 = track_arc_new("arc1", Arc::new(vec![1, 2, 3]));
let arc2 = track_arc_clone("arc2", "arc1", arc1.clone());
```

### Interior Mutability Tracking

Monitor `RefCell` and `Cell` operations with runtime borrow checking:

```rust
use std::cell::{RefCell, Cell};

// RefCell tracking
let cell = track_refcell_new("cell", RefCell::new(42));
let borrow = refcell_borrow!("borrow", "cell", cell.borrow());
let borrow_mut = refcell_borrow_mut!("borrow_mut", "cell", cell.borrow_mut());
refcell_drop!("cell");

// Cell tracking
let cell = track_cell_new("cell", Cell::new(10));
let value = track_cell_get("cell", cell.get());
track_cell_set("cell");
```

### Unsafe Code Tracking

Comprehensive tracking for unsafe operations:

```rust
// Raw pointer operations
let x = 42;
let ptr = track_raw_ptr("ptr", &x as *const i32);
let ptr_mut = track_raw_ptr_mut("ptr_mut", &mut x as *mut i32);
unsafe {
    track_raw_ptr_deref("ptr");
    let value = *ptr;
}

// Unsafe block tracking
unsafe {
    track_unsafe_block_enter("block1");
    // unsafe operations
    track_unsafe_block_exit("block1");
}

// FFI and transmute tracking
track_ffi_call("libc_malloc");
track_transmute("u32_to_f32", "u32", "f32");
track_unsafe_fn_call("dangerous_function");
track_union_field_access("MyUnion", "field1");
```

### Static and Const Tracking

Monitor global variable access patterns:

```rust
// Static variable tracking
static mut COUNTER: i32 = 0;
track_static_init("COUNTER", "COUNTER_id", "i32", true);
track_static_access("COUNTER_id", "COUNTER", true, "main.rs:10");

// Const evaluation tracking
const PI: f64 = 3.14159;
track_const_eval("PI", "PI_id", "f64", "main.rs:5");
```

### Async Tracking

Track async blocks and await expressions:

```rust
// Async block tracking
track_async_block_enter(1, "main.rs:10:5");
// ... async block body ...
track_async_block_exit(1, "main.rs:15:5");

// Await expression tracking
track_await_start(1, "fetch_data", "main.rs:12:9");
// ... await completes ...
track_await_end(1, "main.rs:12:9");
```

### Control Flow Tracking

Track loops, branches, and control flow:

```rust
// Loop tracking
track_loop_enter(1, "for", "main.rs:10:5");
track_loop_iteration(1, 0, "main.rs:10:5");
track_loop_iteration(1, 1, "main.rs:10:5");
track_loop_exit(1, "main.rs:15:5");

// Match tracking
track_match_enter(1, "main.rs:20:5");
track_match_arm(1, 0, "Some(x)", "main.rs:21:9");
track_match_exit(1, "main.rs:25:5");

// Branch tracking
track_branch(1, "then", "main.rs:30:5");

// Return tracking
track_return(1, true, "main.rs:35:5");

// Try operator tracking
track_try(1, "main.rs:40:5");
```

### Method Call Tracking

Track common method calls:

```rust
// Clone tracking
track_clone(1, "data", "main.rs:10:5");

// Lock tracking (Mutex/RwLock)
track_lock(1, "mutex", "guard", "main.rs:15:5");
track_lock(2, "rwlock_read", "reader", "main.rs:20:5");

// Unwrap tracking
track_unwrap(1, "unwrap", "option", "main.rs:25:5");
track_unwrap(2, "expect", "result", "main.rs:30:5");
```

### Advanced API Features

#### Custom ID Correlation

All tracking functions have `_with_id` variants for custom correlation:

```rust
let custom_id = "user_defined_123";
let x = track_new_with_id("x", custom_id, 42);
let r = track_borrow_with_id("r", "r_id", custom_id, &x);
```

#### Event Querying and Filtering

Rich querying capabilities for event analysis:

```rust
// Get all events or filtered subsets
let all_events = get_events();
let new_events = get_new_events();
let borrow_events = get_borrow_events();
let move_events = get_move_events();
let drop_events = get_drop_events();

// Filter events by variable or criteria
let var_events = get_events_for_var("data");
let filtered = get_events_filtered(|event| event.is_unsafe());

// Get event statistics
let counts = get_event_counts();
let summary = get_summary();
print_summary();
```

#### Batch Operations

Efficient batch processing for performance:

```rust
let var_names = vec!["x", "y", "z"];
track_drop_batch(&var_names);
```

### Ownership Graph Analysis

Build and analyze ownership relationships:

```rust
let graph = get_graph();

// Graph statistics
let stats = graph.stats();
println!("Variables: {}, Relationships: {}", 
         stats.total_variables, stats.total_relationships);

// Find specific variables and relationships
let var = graph.find_variable("data");
let borrows = graph.find_borrows("data");

// Analyze ownership patterns
for relationship in &graph.edges {
    match relationship {
        Relationship::BorrowsImmut { from, to, start, end } => {
            println!("{} borrows {} from {} to {}", from, to, start, end);
        }
        Relationship::BorrowsMut { from, to, start, end } => {
            println!("{} mutably borrows {} from {} to {}", from, to, start, end);
        }
        Relationship::Owns { from, to } => {
            println!("{} owns {}", from, to);
        }
    }
}
```

### Lifetime Analysis

Advanced lifetime relationship analysis:

```rust
// Build timeline from events
let timeline = Timeline::from_events(&get_events());

// Analyze lifetime relationships
let relations = timeline.analyze_lifetimes();
for relation in relations {
    match relation {
        LifetimeRelation::Contains { outer, inner } => {
            println!("Lifetime {} contains {}", outer, inner);
        }
        LifetimeRelation::Overlaps { first, second } => {
            println!("Lifetimes {} and {} overlap", first, second);
        }
    }
}

// Detect elision rules
let elision_rules = timeline.detect_elision_rules();
```

### Export and Visualization

Export tracking data for external analysis:

```rust
// Export to JSON file
export_json("ownership_analysis.json").unwrap();

// Manual export with custom data
let events = get_events();
let graph = get_graph();
let export_data = ExportData::new(graph, events);
export_data.to_file("custom_export.json").unwrap();
```

## Event Types

BorrowScope Runtime tracks 40+ event types covering all ownership patterns:

| Category | Events |
|----------|--------|
| **Basic Ownership** | `New`, `Borrow`, `Move`, `Drop` |
| **Smart Pointers** | `RcNew`, `RcClone`, `ArcNew`, `ArcClone` |
| **Interior Mutability** | `RefCellNew`, `RefCellBorrow`, `RefCellDrop`, `CellNew`, `CellGet`, `CellSet` |
| **Static/Const** | `StaticInit`, `StaticAccess`, `ConstEval` |
| **Unsafe Operations** | `RawPtrCreated`, `RawPtrDeref`, `UnsafeBlockEnter`, `UnsafeBlockExit`, `UnsafeFnCall` |
| **FFI/Transmute** | `FfiCall`, `Transmute`, `UnionFieldAccess` |
| **Async** | `AsyncBlockEnter`, `AsyncBlockExit`, `AwaitStart`, `AwaitEnd` |
| **Loops** | `LoopEnter`, `LoopIteration`, `LoopExit` |
| **Control Flow** | `MatchEnter`, `MatchArm`, `MatchExit`, `Branch`, `Return`, `Try` |
| **Method Calls** | `Clone`, `Lock`, `Unwrap` |
| **Access** | `IndexAccess`, `FieldAccess`, `Call`, `Deref` |

All events include timestamps and are serializable to JSON for analysis.

## Architecture

BorrowScope Runtime uses an event sourcing architecture:

1. **Event Recording**: Track operations as timestamped events
2. **Thread-Safe Storage**: Store events in a global, thread-safe tracker
3. **On-Demand Analysis**: Build ownership graphs and timelines from event streams
4. **Export Pipeline**: Serialize data to JSON for visualization tools

Key components:
- **Tracker**: Global event recorder with atomic timestamp generation
- **Event System**: Comprehensive event types with JSON serialization
- **Graph Builder**: Constructs ownership graphs from event streams
- **RAII Guards**: Automatic resource tracking with scope-based cleanup
- **Lifetime Analyzer**: Timeline construction and relationship analysis

## Performance

Optimized for minimal runtime overhead:

- **Single tracking call**: ~75-80ns
- **1000 operations**: ~150μs
- **JSON export (1000 events)**: ~1ms
- **Memory per event**: ~80 bytes
- **Zero cost when disabled**: Complete compile-time elimination

Thread safety achieved through:
- `parking_lot::Mutex` for efficient locking (40-60% faster than std)
- `AtomicU64` for lock-free timestamp generation
- Event sourcing to avoid complex concurrent graph updates

## Feature Flags

- `track` - Enables runtime tracking. Without this feature, all tracking functions compile to no-ops with zero overhead.

```toml
# Development/debugging (with tracking)
[dependencies]
borrowscope-runtime = { version = "0.1", features = ["track"] }

# Production (zero overhead)
[dependencies]
borrowscope-runtime = "0.1"
```

## Testing

Comprehensive test suite with 555+ tests:

```bash
# Run all tests
cargo test --package borrowscope-runtime --features track

# Run specific test categories
cargo test --package borrowscope-runtime --features track --test integration_tests
cargo test --package borrowscope-runtime --features track --test performance_tests
cargo test --package borrowscope-runtime --features track --test unsafe_code_tests

# Run benchmarks
cargo bench --package borrowscope-runtime
```

## Error Handling

Robust error handling with comprehensive error types:

```rust
use borrowscope_runtime::{Result, Error};

match export_json("output.json") {
    Ok(()) => println!("Export successful"),
    Err(Error::SerializationError(e)) => eprintln!("JSON error: {}", e),
    Err(Error::IoError(e)) => eprintln!("File error: {}", e),
    Err(Error::ExportError(msg)) => eprintln!("Export failed: {}", msg),
    Err(Error::InvalidEventSequence(msg)) => eprintln!("Invalid events: {}", msg),
    Err(Error::LockError(msg)) => eprintln!("Lock error: {}", msg),
}
```

## Documentation

Generate and view complete API documentation:

```bash
cargo doc --package borrowscope-runtime --features track --open
```

## License

Licensed under the Apache License, Version 2.0. See the main BorrowScope repository for full license information.