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
# 核心模块 (Core Module)

## 概述

核心模块为 memscope-rs 库提供基础内存追踪功能。它实现了拦截、追踪和分析 Rust 应用程序中内存分配所需的底层基础设施。

## 组件

### 1. TrackingAllocator(追踪分配器)

**文件**: `src/core/allocator.rs`

**用途**: 自定义全局分配器,拦截应用程序中的所有堆分配和释放操作。

**核心功能**:
- 实现 `GlobalAlloc` trait 以覆盖系统分配器
- 追踪每个堆分配和释放操作
- 使用线程本地存储标志防止递归追踪
- 基于分配大小提供类型推断
- 恐慌安全操作

**源代码**:

```rust
pub struct TrackingAllocator;

thread_local! {
    static TRACKING_DISABLED: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
}

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
    }

    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        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_deallocation(ptr as usize);
            }

            TRACKING_DISABLED.with(|disabled| disabled.set(false));
        }

        System.dealloc(ptr, layout);
    }
}
```

**设计理念**:

1. **零开销追踪**: 使用线程本地存储标志而非锁,最小化性能影响
2. **递归保护**: 在追踪操作期间禁用追踪,防止无限循环
3. **恐慌恢复**: 追踪失败不会导致应用崩溃
4. **类型推断**: 基于分配大小模式提供基本类型信息

**类型推断实现**:

```rust
fn _infer_type_from_allocation_context(size: usize) -> &'static str {
    match size {
        // 常见 Rust 类型大小
        1 => "u8",
        2 => "u16",
        4 => "u32",
        8 => "u64",
        16 => "u128",

        // String 和 Vec 常见大小
        24 => "String",
        32 => "Vec<T>",
        48 => "HashMap<K,V>",

        // 智能指针大小
        size if size == std::mem::size_of::<std::sync::Arc<String>>() => "Arc<T>",
        size if size == std::mem::size_of::<std::rc::Rc<String>>() => "Rc<T>",
        size if size == std::mem::size_of::<Box<String>>() => "Box<T>",

        // 其他大小的默认值
        _ => "unknown",
    }
}
```

**使用方法**:

```rust
// 在 main.rs 或 lib.rs 中
use memscope::core::TrackingAllocator;

#[global_allocator]
static GLOBAL_ALLOCATOR: TrackingAllocator = TrackingAllocator;

fn main() {
    // 所有堆分配现在都会自动追踪
    let data = vec![1, 2, 3, 4, 5];
    let string = String::from("Hello");
}
```

### 2. 错误处理

**文件**: `src/core/error.rs`

**用途**: 整个 memscope-rs 库的统一错误处理系统。

**核心功能**:
- 使用 `Arc<str>` 简化高效的错误类型,减少字符串克隆
- 错误分类(内存、分析、导出、配置、系统、内部)
- 错误严重级别(低、中、高、严重)
- 错误恢复机制
- 与旧错误类型的向后兼容性

**错误类型**:

```rust
pub enum MemScopeError {
    Memory {
        operation: MemoryOperation,
        message: Arc<str>,
        context: Option<Arc<str>>,
    },

    Analysis {
        analyzer: Arc<str>,
        message: Arc<str>,
        recoverable: bool,
    },

    Export {
        format: Arc<str>,
        message: Arc<str>,
        partial_success: bool,
    },

    Configuration {
        component: Arc<str>,
        message: Arc<str>,
    },

    System {
        error_type: SystemErrorType,
        message: Arc<str>,
        source_message: Option<Arc<str>>,
    },

    Internal {
        message: Arc<str>,
        location: Option<Arc<str>>,
    },
}
```

**错误严重级别**:

```rust
pub enum ErrorSeverity {
    Low,      // 警告,部分失败
    Medium,   // 操作失败
    High,     // 关键分析失败
    Critical, // 内部错误,bug
}
```

**错误恢复**:

```rust
pub enum RecoveryAction {
    Retry { max_attempts: u32, delay_ms: u64 },
    UseDefault { value: String },
    Skip,
    Abort,
    Fallback { strategy: String },
}

pub trait ErrorRecovery {
    fn can_recover(&self, error: &MemScopeError) -> bool;
    fn get_recovery_action(&self, error: &MemScopeError) -> Option<RecoveryAction>;
    fn execute_recovery(&self, action: &RecoveryAction) -> Result<()>;
}
```

**设计理念**:

1. **性能**: 使用 `Arc<str>` 而非 `String` 减少克隆开销
2. **分类**: 清晰的错误类型分离以便更好地处理
3. **可恢复性**: 标记错误为可恢复或不可恢复以便适当响应
4. **向后兼容**: 自动将旧错误类型转换为新格式

**使用方法**:

```rust
use memscope::core::error::{MemScopeError, MemoryOperation};

fn allocate_memory(size: usize) -> Result<*mut u8, MemScopeError> {
    if size == 0 {
        return Err(MemScopeError::memory_with_context(
            MemoryOperation::Allocation,
            "零大小分配",
            "在 allocate_memory 中",
        ));
    }

    // ... 分配逻辑
    Ok(ptr)
}
```

### 3. 作用域追踪器

**文件**: `src/core/scope_tracker.rs`

**用途**: 追踪变量生命周期和作用域层次结构以进行内存分析。

**核心功能**:
- 每线程作用域堆栈追踪
- 作用域层次结构和关系追踪
- 变量与作用域关联
- 作用域生命周期指标
- 使用 RAII 自动作用域管理

**核心实现**:

```rust
pub struct ScopeTracker {
    pub active_scopes: RwLock<HashMap<ScopeId, ScopeInfo>>,
    pub completed_scopes: Mutex<Vec<ScopeInfo>>,
    pub scope_hierarchy: Mutex<ScopeHierarchy>,
    next_scope_id: AtomicU64,
    pub scope_stack: RwLock<HashMap<String, Vec<ScopeId>>>,
}

impl ScopeTracker {
    pub fn enter_scope(&self, name: String) -> TrackingResult<ScopeId> {
        let scope_id = self.allocate_scope_id();
        let thread_id = format!("{:?}", std::thread::current().id());
        let timestamp = current_timestamp();

        // 确定父作用域和深度
        let (parent_scope, depth) = {
            let stack = self.scope_stack.read().unwrap();
            if let Some(thread_stack) = stack.get(&thread_id) {
                if let Some(&parent_id) = thread_stack.last() {
                    let active = self.active_scopes.read().unwrap();
                    if let Some(parent) = active.get(&parent_id) {
                        (Some(parent.name.clone()), parent.depth + 1)
                    } else {
                        (None, 0)
                    }
                } else {
                    (None, 0)
                }
            } else {
                (None, 0)
            }
        };

        // 创建并注册作用域信息
        let scope_info = ScopeInfo {
            name: name.clone(),
            parent: parent_scope.clone(),
            children: Vec::new(),
            depth,
            variables: Vec::new(),
            total_memory: 0,
            peak_memory: 0,
            allocation_count: 0,
            lifetime_start: Some(timestamp as u64),
            lifetime_end: None,
            is_active: true,
            start_time: timestamp as u64,
            end_time: None,
            memory_usage: 0,
            child_scopes: Vec::new(),
            parent_scope: parent_scope.clone(),
        };

        self.active_scopes.write().unwrap().insert(scope_id, scope_info);
        self.scope_stack.write().unwrap()
            .entry(thread_id.clone())
            .or_default()
            .push(scope_id);

        Ok(scope_id)
    }
}
```

**RAII 作用域守卫**:

```rust
pub struct ScopeGuard {
    scope_id: ScopeId,
    tracker: Arc<ScopeTracker>,
}

impl ScopeGuard {
    pub fn enter(name: &str) -> TrackingResult<Self> {
        let tracker = get_global_scope_tracker();
        let scope_id = tracker.enter_scope(name.to_string())?;
        Ok(Self { scope_id, tracker })
    }
}

impl Drop for ScopeGuard {
    fn drop(&mut self) {
        let _ = self.tracker.exit_scope(self.scope_id);
    }
}
```

**设计理念**:

1. **线程本地追踪**: 每个线程维护自己的作用域堆栈
2. **层次感知**: 追踪作用域之间的父子关系
3. **自动清理**: 使用 RAII 模式自动退出作用域
4. **性能**: 使用原子操作进行作用域 ID 分配

**使用方法**:

```rust
use memscope::core::scope_tracker::ScopeGuard;

fn process_data() {
    // 进入作用域并自动清理
    let _guard = ScopeGuard::enter("process_data").unwrap();

    // 变量自动与此作用域关联
    let data = vec![1, 2, 3, 4, 5];

    // 嵌套作用域
    {
        let _nested_guard = ScopeGuard::enter("inner_scope").unwrap();
        let temp = String::from("temporary");
    } // 内层作用域自动退出

} // 外层作用域自动退出
```

**宏使用**:

```rust
// 简单作用域追踪
track_scope!("function_name");

// 带代码块的作用域
track_scope!("block_name", {
    let data = vec![1, 2, 3];
    // ... 处理
});
```

## 设计原则

### 1. 零开销
核心模块设计为具有最小的性能影响:
- 使用线程本地存储而非锁
- 避免在追踪操作期间进行分配
- 使用静态字符串进行类型推断

### 2. 恐慌安全
所有操作都是恐慌安全的:
- 追踪失败不会导致应用崩溃
- 使用 `catch_unwind` 处理追踪代码中的恐慌
- 追踪失败时优雅降级

### 3. 线程安全
所有共享状态都正确同步:
- 使用 `RwLock` 处理读密集型数据结构
- 使用 `Mutex` 处理写密集型数据结构
- 使用 `AtomicU64` 处理计数器

### 4. 类型安全
强类型系统确保正确性:
- 自定义错误类型防止无效操作
- Result 类型强制错误处理
- 类型推断提供额外上下文

## 性能考虑

### 线程本地存储
使用线程本地存储标志而非锁:
- **优势**: 线程间无锁竞争
- **权衡**: 每个线程有自己的追踪状态

### 静态字符串
使用静态字符串进行类型推断:
- **优势**: 追踪期间无分配
- **权衡**: 类型信息有限

### 原子操作
使用原子操作处理计数器:
- **优势**: 无锁性能
- **权衡**: 仅限于简单操作

## 测试

核心模块包含全面的测试:

```rust
#[test]
fn test_allocation_tracking() {
    let allocator = TrackingAllocator::new();
    let layout = Layout::from_size_align(1024, 8).unwrap();

    unsafe {
        let ptr = allocator.alloc(layout);
        assert!(!ptr.is_null());
        allocator.dealloc(ptr, layout);
    }
}

#[test]
fn test_recursive_allocation_handling() {
    // 验证递归分配不会导致无限循环
    let allocator = TrackingAllocator::new();
    let layout = Layout::from_size_align(64, 8).unwrap();

    unsafe {
        let ptr = allocator.alloc(layout);
        if !ptr.is_null() {
            allocator.dealloc(ptr, layout);
        }
    }
}
```

## 集成

核心模块与 memscope-rs 库的其余部分集成:

```
core/
  ↓
tracker/      (使用 TrackingAllocator)
  ↓
capture/      (追踪分配事件)
  ↓
analysis/     (分析作用域数据)
  ↓
render/       (可视化作用域层次结构)
```

## 最佳实践

1. **全局分配器**: 在程序启动时设置一次追踪分配器为全局分配器
2. **错误处理**: 始终适当处理 `MemScopeError`
3. **作用域管理**: 使用 `ScopeGuard` 进行自动清理
4. **性能**: 在生产环境中使用采样减少开销

## 限制

1. **类型推断**: 仅限于常见类型大小
2. **栈变量**: 仅追踪堆分配
3. **静态变量**: 不追踪静态变量
4. **外部内存**: 除非外部库使用全局分配器,否则不追踪外部库分配的内存

## 未来改进

1. **更好的类型推断**: 与编译器集成以获取准确的类型信息
2. **栈追踪**: 追踪栈分配
3. **变量名**: 捕获实际变量名(目前使用推断的名称)
4. **性能**: 进一步优化追踪开销