Rust内存转储库minidumper的使用,minidumper提供轻量级进程崩溃分析和调试信息捕获功能

以下是关于Rust内存转储库minidumper的完整使用示例,基于您提供的内容:

完整示例代码

use minidumper::{Client, Server, ServerHandler};
use std::path::PathBuf;
use std::thread;
use std::time::Duration;

// 自定义服务器处理程序
struct CrashHandler;

impl ServerHandler for CrashHandler {
    // 处理客户端发送的消息
    fn on_message(&self, message: String) {
        println!("[服务端] 收到消息: {}", message);
    }

    // 创建minidump文件路径
    fn create_minidump_file(&self) -> std::io::Result<PathBuf> {
        // 使用时间戳创建唯一的dump文件名
        let timestamp = chrono::Local::now().format("%Y%m%d_%H%M%S");
        let path = PathBuf::from(format!("crash_{}.dmp", timestamp));
        println!("[服务端] 创建转储文件: {:?}", path);
        Ok(path)
    }

    // minidump创建完成回调
    fn on_minidump_created(&self, result: Result<PathBuf, minidumper::Error>) {
        match result {
            Ok(path) => {
                println!("[服务端] Minidump创建成功: {:?}", path);
                // 这里可以添加上传到崩溃分析服务器的逻辑
            },
            Err(e) => eprintln!("[服务端] 创建minidump失败: {}", e),
        }
    }
}

fn main() {
    // 服务端初始化
    let app_name = "crash_monitor_app";
    println!("[服务端] 启动崩溃监控服务...");
    let (server, server_thread) = Server::create(app_name, CrashHandler).unwrap();

    // 模拟客户端进程
    thread::spawn(move || {
        thread::sleep(Duration::from_secs(1));
        
        println!("[客户端] 连接服务端...");
        let mut client = Client::connect(app_name).unwrap();
        
        // 发送应用状态信息
        client.send_message("应用状态: 正常运行".to_string()).unwrap();
        
        // 模拟崩溃
        thread::sleep(Duration::from_secs(2));
        println!("[客户端] 检测到崩溃条件,请求内存转储...");
        client.request_dump().unwrap();
    });

    // 等待10秒后关闭服务
    thread::sleep(Duration::from_secs(10));
    println!("[服务端] 关闭服务...");
    server.shutdown();
    server_thread.join().unwrap();
}

示例说明

  1. 服务端实现

    • 创建CrashHandler实现ServerHandler trait
    • 包含消息处理、转储文件创建和转储完成回调三个主要方法
    • 使用时间戳生成唯一的dump文件名
  2. 客户端模拟

    • 在独立线程中模拟客户端进程
    • 连接服务端后发送状态消息
    • 模拟崩溃并请求内存转储
  3. 运行流程

    • 服务端启动并等待客户端连接
    • 客户端连接后发送状态信息
    • 客户端"崩溃"时请求转储
    • 服务端创建minidump文件并回调通知

使用建议

  1. 在生产环境中,建议在on_minidump_created回调中添加:

    • 崩溃日志记录
    • 转储文件上传功能
    • 通知机制
  2. 可以扩展ServerHandler实现更复杂的崩溃处理逻辑

  3. 客户端可以定期发送心跳信息用于监控应用状态

这个示例完整演示了minidumper库的核心功能,包括进程间通信、崩溃处理和内存转储创建。


1 回复

Rust内存转储库minidumper使用指南

下面是基于提供的内容整理的完整示例demo:

完整示例:集成崩溃报告与自定义分析的应用程序

use minidumper::{MiniDumper, MiniDumperConfig, DumpCallback};
use std::path::Path;
use std::fs;

// 自定义崩溃回调处理器
struct AdvancedCrashReporter {
    upload_url: String,
}

impl DumpCallback for AdvancedCrashReporter {
    fn on_dump_created(&self, path: &Path) {
        println!("[CRASH REPORT] Minidump generated at: {:?}", path);
        
        // 1. 记录崩溃基本信息
        if let Ok(metadata) = fs::metadata(path) {
            println!("- File size: {} bytes", metadata.len());
        }
        
        // 2. 读取并记录前1KB内容(示例)
        if let Ok(data) = fs::read(path) {
            let sample = &data[..std::cmp::min(1024, data.len())];
            println!("- Hex dump (first 1KB): {:x?}", sample);
        }
        
        // 3. 模拟上传到服务器
        println!("- Uploading to {}... (simulated)", self.upload_url);
    }
}

fn main() {
    // 配置minidumper
    let config = MiniDumperConfig::new()
        .dump_path("./crash_reports")  // 崩溃报告保存目录
        .with_threads(true)           // 包含线程信息
        .with_modules(true)           // 包含模块信息
        .with_memory(true)            // 包含内存内容
        .filter_module(|name| {       // 模块过滤
            !name.contains("test")    // 排除测试模块
        })
        .callback(Box::new(AdvancedCrashReporter {
            upload_url: "https://example.com/crash-reports".to_string(),
        }));
    
    // 初始化minidumper
    let _dumper = MiniDumper::initialize(config)
        .expect("Failed to initialize crash reporter");

    // 安装信号处理器(Unix-like系统需要)
    #[cfg(unix)]
    minidumper::install_signal_handler()
        .expect("Failed to install signal handler");

    println!("Application started (PID: {})", std::process::id());
    println!("Press CTRL+C to exit gracefully or enter 'crash' to simulate a crash");

    // 简单的控制台交互
    loop {
        let mut input = String::new();
        std::io::stdin().read_line(&mut input).unwrap();
        
        match input.trim() {
            "crash" => {
                println!("Simulating crash...");
                // 模拟空指针解引用崩溃
                unsafe {
                    std::ptr::null_mut::<i32>().write(42);
                }
            },
            "dump" => {
                println!("Generating manual dump...");
                // 手动生成转储文件
                if let Err(e) = _dumper.dump_minidump("manual.dmp") {
                    eprintln!("Manual dump failed: {}", e);
                }
            },
            "exit" | "quit" => {
                println!("Exiting gracefully...");
                break;
            },
            _ => println!("Unknown command"),
        }
    }
}

示例说明

  1. 自定义回调处理

    • 实现了AdvancedCrashReporter结构体来处理转储文件生成事件
    • 包含基本的文件信息收集和模拟上传功能
  2. 增强的配置

    • 设置了转储路径./crash_reports
    • 启用了线程、模块和内存信息收集
    • 添加了模块过滤规则
  3. 交互式测试

    • 支持三种命令:
      • crash - 模拟崩溃
      • dump - 手动生成转储文件
      • exit - 正常退出
  4. 跨平台支持

    • 包含Unix-like系统的信号处理器安装

如何运行测试

  1. 创建新项目并添加依赖:
[dependencies]
minidumper = "0.1"
  1. 将上面的完整示例代码复制到main.rs

  2. 运行程序:

cargo run
  1. 在程序运行时:
  • 输入crash测试崩溃转储
  • 输入dump测试手动转储
  • 输入exit退出程序

生成的转储文件会保存在./crash_reports目录中,可以使用minidump分析工具进一步分析。

回到顶部