memscope-rs 0.2.3

A memory tracking library for Rust applications.
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
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
# Architecture

## Overview

memscope-rs is a comprehensive memory tracking and analysis library for Rust applications. It provides a modular architecture that separates concerns across multiple layers, enabling efficient memory monitoring, analysis, and visualization.

## System Architecture

```
User Code
   ↓
Facade Layer (facade/)
   ↓
Capture Engine (capture/)
   ↓
Event Storage (event_store/)
   ↓
Metadata Engine (metadata/)
   ↓
Snapshot Engine (snapshot/)
   ↓
Query Engine (query/)
   ↓
Analysis Engine (analysis/)
   ↓
Render Engine (render_engine/)
   ↓
Output (JSON/HTML/Binary)
```

## Module Responsibilities

### Core Layer (core/)

**Purpose**: Provides fundamental memory tracking capabilities and type definitions.

**Components**:
- `allocator.rs`: Custom global allocator that intercepts all heap allocations
- `error.rs`: Error type definitions
- `scope_tracker.rs`: Scope tracking for variable lifetimes
- `safe_operations.rs`: Safe operation utilities
- `call_stack_normalizer.rs`: Call stack normalization
- `unwrap_safe.rs`: Safe unwrap utilities

**Key Implementation**:

```rust
// src/core/allocator.rs
unsafe impl GlobalAlloc for TrackingAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        let ptr = System.alloc(layout);
        if !ptr.is_null() {
            let should_track = TRACKING_DISABLED.with(|disabled| !disabled.get());
            if should_track {
                TRACKING_DISABLED.with(|disabled| disabled.set(true));
                if let Ok(tracker) = std::panic::catch_unwind(crate::core::tracker::get_tracker) {
                    let _ = tracker.track_allocation(ptr as usize, layout.size());
                }
                TRACKING_DISABLED.with(|disabled| disabled.set(false));
            }
        }
        ptr
    }
}
```

**Design Principles**:
- **Zero-overhead**: Uses TLS flags instead of locks
- **Recursive protection**: Prevents infinite tracking loops
- **Panic resilience**: Tracking failures don't crash the application
- **Type inference**: Tracks types based on allocation size

### Tracker Layer (tracker.rs)

**Purpose**: Provides a unified tracking API and macros for users.

**Key Features**:
- Automatic variable name and type capture
- System monitoring (CPU, memory, disk, network)
- Per-thread independent tracking
- Configurable sampling rate
- Automatic hotspot detection
- JSON/HTML export support

**Macro Usage**:

```rust
let tracker = tracker!();

let data = vec![1, 2, 3, 4, 5];
track!(tracker, data);
```

**Sampling Support**:

```rust
pub fn track_as<T: Trackable>(&self, var: &T, name: &str, file: &str, line: u32) {
    if let Ok(cfg) = self.config.lock() {
        if cfg.sampling.sample_rate < 1.0 {
            let hash = compute_hash(timestamp, thread_id, name, file, line);
            let threshold = (cfg.sampling.sample_rate * 1000.0) as u64;
            if (hash % 1000) > threshold {
                return;
            }
        }
    }
    self.track_inner(var, name, file, line);
}
```

### Capture Engine (capture/)

**Purpose**: Captures memory events from the application using various backend strategies.

**Backend Types**:
- `CoreTracker`: Single-threaded, simple, low overhead
- `LockfreeTracker`: Multi-threaded, thread-local storage
- `AsyncTracker`: Async task tracking with task IDs
- `UnifiedTracker`: Automatic detection based on CPU core count

**Key Types**:

```rust
pub enum CaptureBackendType {
    Core,
    Lockfree,
    Async,
    Unified,
}

pub struct AllocationInfo {
    pub ptr: usize,
    pub size: usize,
    pub var_name: Option<String>,
    pub type_name: Option<String>,
    pub timestamp_alloc: u64,
    pub timestamp_dealloc: Option<u64>,
    pub thread_id: ThreadId,
    pub thread_id_u64: u64,
}
```

**Analysis Features**:
- Hotspot analysis
- Bottleneck analysis
- Task-level memory profiling
- Efficiency scoring
- Resource ranking

### Event Storage (event_store/)

**Purpose**: Centralized storage for all memory events using lock-free queues.

**Key Implementation**:

```rust
pub struct EventStore {
    // Lock-free queue for events
}

impl EventStore {
    pub fn record(&self, event: MemoryEvent) {
        // Record event to lock-free queue
    }

    pub fn snapshot(&self) -> Vec<MemoryEvent> {
        // Get event snapshot
    }
}

pub enum MemoryEventType {
    Allocate,
    Deallocate,
    Reallocate,
    Move,
    Borrow,
    Clone,
}
```

**Design Principles**:
- **Lock-free**: High-performance concurrent access
- **Append-only**: Efficient event recording
- **Snapshot support**: Point-in-time state capture

### Metadata Engine (metadata/)

**Purpose**: Centralized management of all metadata including variables, scopes, and threads.

**Components**:
- `VariableRegistry`: Variable metadata management
- `ScopeTracker`: Scope tracking for variable lifetimes
- `ThreadRegistry`: Thread metadata management
- `SmartPointers`: Smart pointer information
- `StackTrace`: Call stack information

**Key Implementation**:

```rust
pub struct MetadataEngine {
    pub variable_registry: Arc<VariableRegistry>,
    pub scope_tracker: Arc<ScopeTracker>,
    pub thread_registry: Arc<ThreadRegistry>,
}

impl MetadataEngine {
    pub fn new() -> Self {
        Self {
            variable_registry: Arc::new(VariableRegistry::new()),
            scope_tracker: Arc::new(ScopeTracker::new()),
            thread_registry: Arc::new(ThreadRegistry::new()),
        }
    }
}
```

### Snapshot Engine (snapshot/)

**Purpose**: Builds memory snapshots from event data.

**Key Implementation**:

```rust
pub struct SnapshotEngine {
    event_store: SharedEventStore,
}

impl SnapshotEngine {
    pub fn build_snapshot(&self) -> MemorySnapshot {
        // Build snapshot from events
    }
}

pub struct MemorySnapshot {
    pub allocations: Vec<ActiveAllocation>,
    pub stats: MemoryStats,
    pub timestamp: u64,
}

pub struct ActiveAllocation {
    pub ptr: usize,
    pub size: usize,
    pub var_name: Option<String>,
    pub type_name: Option<String>,
    pub allocated_at: u64,
    pub thread_id: ThreadId,
    pub thread_id_u64: u64,
}
```

### Query Engine (query/)

**Purpose**: Provides unified query interface for accessing memory data.

**Query Types**:

```rust
pub enum Query {
    Allocation(AllocationQuery),
    Thread(ThreadQuery),
    Summary(SummaryQuery),
}

pub enum QueryResult {
    Allocation(AllocationQueryResult),
    Thread(ThreadQueryResult),
    Summary(SummaryQueryResult),
}
```

### Analysis Engine (analysis/)

**Purpose**: Analyzes memory data to detect issues and provide insights.

**Detectors**:
- `LeakDetector`: Memory leak detection
- `UafDetector`: Use-after-free detection
- `OverflowDetector`: Buffer overflow detection
- `SafetyDetector`: Safety violation detection
- `LifecycleDetector`: Lifecycle analysis

**Detector Interface**:

```rust
pub trait Detector {
    fn name(&self) -> &str;
    fn detect(&self, allocations: &[AllocationInfo]) -> DetectionResult;
    fn get_config(&self) -> &DetectorConfig;
}

pub struct DetectionResult {
    pub issues: Vec<Issue>,
    pub statistics: DetectionStatistics,
}
```

**Additional Analysis**:
- Circular reference detection
- Unsafe FFI tracking
- Async pattern analysis
- Borrow pattern analysis
- Generic type analysis
- Closure analysis

### Timeline Engine (timeline/)

**Purpose**: Time-based memory analysis and replay.

**Components**:
- `TimelineIndex`: Time-based indexing
- `TimelineQuery`: Time-based queries
- `TimelineReplay`: Event replay functionality

### Render Engine (render_engine/)

**Purpose**: Renders output data in various formats.

**Output Formats**:
- JSON
- HTML (interactive dashboard)
- Binary
- SVG

**Export Functions**:

```rust
pub fn export_all_json(output_path: &str, tracker: &Tracker, ...) -> Result<()>
pub fn export_dashboard_html(output_path: &str, tracker: &Tracker, ...) -> Result<()>
pub fn export_snapshot_to_json(snapshot: &MemorySnapshot, path: &Path, options: &ExportJsonOptions) -> Result<()>
pub fn export_leak_detection_json(detection_result: &DetectionResult, path: &Path) -> Result<()>
pub fn export_memory_passports_json(passports: &[MemoryPassport], path: &Path) -> Result<()>
pub fn export_unsafe_ffi_json(stats: &UnsafeFFIStats, path: &Path) -> Result<()>
```

### Facade Layer (facade/)

**Purpose**: Provides a unified facade interface that integrates all engines.

**Key Implementation**:

```rust
pub struct MemScope {
    pub event_store: Arc<EventStore>,
    pub capture: Arc<CaptureEngine>,
    pub metadata: Arc<MetadataEngine>,
    pub snapshot: Arc<SnapshotEngine>,
    pub query: Arc<QueryEngine>,
    pub analysis: Arc<Mutex<AnalysisEngine>>,
    pub timeline: Arc<TimelineEngine>,
    pub render: Arc<RenderEngine>,
}

impl MemScope {
    pub fn new() -> Self {
        // Create all engines and connect them
        let event_store = Arc::new(EventStore::new());
        let capture = Arc::new(CaptureEngine::new(CaptureBackendType::Unified, event_store.clone()));
        // ... create other engines

        Self {
            event_store,
            capture,
            metadata,
            snapshot,
            query,
            analysis,
            timeline,
            render,
        }
    }

    pub fn run_leak_detector(&self) -> DetectionResult {
        self.analysis.lock().unwrap().run_detector(LeakDetector::new(...))
    }

    pub fn export_html(&self, path: &str) -> Result<()> {
        self.render.export_html(path, ...)
    }
}
```

### Error Handling (error/)

**Purpose**: Unified error handling with context and recovery strategies.

**Error Types**:

```rust
pub struct MemScopeError {
    pub kind: ErrorKind,
    pub severity: ErrorSeverity,
    pub context: ErrorContext,
    pub source: Option<Box<dyn std::error::Error>>,
}

pub enum ErrorKind {
    AllocationError,
    TrackingError,
    AnalysisError,
    RenderError,
    ExportError,
}

pub enum ErrorSeverity {
    Warning,
    Error,
    Critical,
}

pub enum RecoveryAction {
    Retry,
    Skip,
    Abort,
    Recover,
}
```

### Derive Macro (memscope-derive/)

**Purpose**: Provides procedural macro for automatically implementing the `Trackable` trait.

**Key Implementation**:

```rust
#[proc_macro_derive(Trackable)]
pub fn derive_trackable(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);

    match &input.data {
        Data::Struct(data_struct) => {
            let heap_ptr_impl = generate_heap_ptr_impl(&data_struct.fields);
            let size_estimate_impl = generate_size_estimate_impl(&data_struct.fields);
            let internal_allocations_impl = generate_internal_allocations_impl(&data_struct.fields);

            quote! {
                impl Trackable for #name {
                    fn get_heap_ptr(&self) -> Option<usize> { #heap_ptr_impl }
                    fn get_type_name(&self) -> &'static str { stringify!(#name) }
                    fn get_size_estimate(&self) -> usize { #size_estimate_impl }
                    fn get_internal_allocations(&self, var_name: &str) -> Vec<(usize, String)> {
                        #internal_allocations_impl
                    }
                }
            }
        }
        Data::Enum(data_enum) => { /* ... */ }
        Data::Union(_) => { /* Not supported */ }
    }
}
```

### Trackable Trait

**Purpose**: Marks types that can be tracked by the memory tracker.

**Trait Definition**:

```rust
pub trait Trackable {
    fn get_heap_ptr(&self) -> Option<usize>;
    fn get_type_name(&self) -> &'static str;
    fn get_size_estimate(&self) -> usize;
    fn get_ref_count(&self) -> Option<usize> { None }
    fn get_data_ptr(&self) -> Option<usize>;
    fn get_data_size(&self) -> Option<usize>;
}
```

**Built-in Implementations**:
- `Vec<T>`
- `String`
- `HashMap<K, V>`
- `Box<T>`
- `Arc<T>`
- `Rc<T>`

## Data Flow

### Tracking Flow

```
1. User code uses track!() macro
   2. Tracker captures variable information
   3. CaptureEngine records allocation events
   4. EventStore stores events in lock-free queue
   5. MetadataEngine manages metadata
   6. SnapshotEngine builds snapshots
```

### Analysis Flow

```
1. SnapshotEngine provides memory snapshot
   2. QueryEngine queries specific data
   3. AnalysisEngine runs detectors
   4. Detection results generated
   5. RenderEngine renders output
   6. Export to JSON/HTML/Binary
```

### Export Flow

```
1. User calls export function
   2. RenderEngine retrieves data from SnapshotEngine
   3. Data formatted according to output format
   4. Write to file system
```

## Design Patterns

### Facade Pattern
`MemScope` provides a unified interface to all engines, simplifying user interaction.

### Strategy Pattern
`CaptureBackend` supports multiple tracking strategies (Core, Lockfree, Async, Unified).

### Observer Pattern
Event storage and event recording use observer pattern for event handling.

### Factory Pattern
Backend creation and configuration use factory pattern.

### Adapter Pattern
Detectors are adapted to work with the analysis engine.

### Builder Pattern
Configuration objects use builder pattern for flexible construction.

### Singleton Pattern
Global tracker uses singleton pattern for shared state.

## Architecture Principles

### 1. Layered Architecture
Clear separation of concerns across multiple layers, each with a specific responsibility.

### 2. Modular Design
Each module has a single, well-defined responsibility, making the codebase easy to understand and maintain.

### 3. Type Safety
Strong type system ensures memory safety and prevents many common errors.

### 4. Thread Safety
Uses `Arc` and `Mutex` for shared state, ensuring thread-safe concurrent access.

### 5. Zero-Overhead Tracking
Uses TLS flags instead of locks to minimize performance impact.

### 6. Async Support
Designed with async tasks in mind, supporting task ID tracking.

### 7. Extensibility
Easy to add new detectors, backends, and export formats.

## Performance Considerations

### Lock-Free Queues
Event storage uses lock-free queues for high-performance concurrent access.

### Sampling
Supports configurable sampling rates to reduce overhead in production environments.

### TLS Flags
Uses thread-local storage flags instead of locks to prevent recursive tracking.

### Panic Resilience
Tracking failures are handled gracefully without crashing the application.

### Bounded History
Event storage supports bounded history to limit memory usage.

## Security Considerations

### Panic Safety
All operations are panic-safe, ensuring tracking failures don't crash the application.

### Type Safety
Strong type system prevents memory safety violations.

### Thread Safety
All shared state is properly synchronized using `Arc` and `Mutex`.

### Recursive Protection
Tracking is disabled during tracking operations to prevent infinite loops.

## Additional Modules

For detailed documentation on individual modules, see:

- [Analysis Engine](modules/analysis_engine.md) - Pluggable memory analysis
- [Event Store](modules/event_store.md) - Lock-free event storage
- [Facade](modules/facade.md) - Unified interface
- [Render Engine](modules/render_engine.md) - Multi-format output
- [Timeline](modules/timeline.md) - Time-based analysis
- [Error Handling](modules/error.md) - Error types and recovery
- [Variable Registry](modules/variable_registry.md) - Variable name tracking
- [Metadata](modules/metadata.md) - Thread and variable metadata

## Dependencies

### External Dependencies
- `serde`: Serialization/deserialization
- `serde_json`: JSON support
- `std`: Standard library

### Internal Dependencies
- `memscope-derive`: Procedural macro for `Trackable` trait

## Conclusion

memscope-rs provides a comprehensive, modular architecture for memory tracking and analysis in Rust applications. The layered design ensures clear separation of concerns, while the modular approach allows for easy extension and maintenance. The architecture prioritizes performance, safety, and usability, making it suitable for both development and production environments.