Crashpad 在windows下编译和使用指南

在 Windows 下为你的应用程序集成 Crashpad,可以在程序崩溃时自动捕获并生成崩溃转储文件(dmp),这对于定位和修复疑难问题非常有帮助。下面梳理安装、配置、集成到项目以及后续分析调试的完整流程。

📋 前期准备

开始之前,你需要确保系统中已准备好以下工具:

  • 编译环境:Visual Studio 2019 或更高版本是必须的。
  • 构建工具 :需要 GitCMake 。同时,Crashpad 的编译依赖 Chromium 的构建工具 depot_tools
  • Python:需要 Python 来执行编译脚本。

🔧 编译 Crashpad

  1. 获取源码:使用 Git 克隆 Crashpad 的源代码仓库到本地。

    bash 复制代码
    git clone https://chromium.googlesource.com/crashpad/crashpad

    或者,你也可以直接前往 https://github.com/chromium/crashpad 下载。(需要翻墙哦😂)

  2. 同步依赖 :进入 crashpad 目录,使用 gclient 同步第三方库。

    bash 复制代码
    cd crashpad
    gclient sync
  3. 生成构建文件:使用 GN 或 GYP 生成构建文件。

    • GN 方式(推荐,但请注意搜索结果中提及 Crashpad 传统上使用 GYP,未来可能转向 GN。目前主流方式可能是 GN,建议查阅 Crashpad 官方文档确认):
    bash 复制代码
    gn gen out/Default
    • GYP 方式(传统方式):
    bash 复制代码
    set DEPOT_TOOLS_WIN_TOOLCHAIN=0
    set GYP_GENERATORS=msvs-ninja,ninja
    python build/gyp_crashpad.py
  4. 编译:使用 Ninja 进行编译。

    bash 复制代码
    ninja -C out/Default

    编译成功后,在 out/Default 目录下会找到 crashpad_handler.exe 和编译出的库文件(如 crashpad_lib.lib)。

⚙️ 集成到你的项目

包含头文件和库

将 Crashpad 的 include 目录添加到项目的头文件包含路径中,并将编译好的库文件路径添加到库目录。

链接库文件

在你的项目中,需要链接以下 Crashpad 库(根据你的编译情况,库名可能略有不同):

  • base.lib
  • client.lib
  • util.lib
  • common.lib

此外,还需要系统库 Advapi32.lib

初始化 Crashpad

在你的应用程序启动代码中(通常是 main 函数或 WinMain 函数的开头),添加 Crashpad 的初始化代码:

cpp 复制代码
#include <client/crashpad_client.h>
#include <client/crashpad_info.h>
#include <client/settings.h>
#include <client/crash_report_database.h>

// 为了避免 Windows.h 中的 min/max 宏与 std::min/std::max 冲突,可在包含 Windows.h 前定义 NOMINMAX
#define NOMINMAX
#include <windows.h>

std::unique_ptr<crashpad::CrashReportDatabase> database;

static bool startCrashHandler(const std::string& url, 
                              const std::wstring& handler_path, 
                              const std::wstring& db_path) {
    using namespace crashpad;

    std::map<std::string, std::string> annotations;
    std::vector<std::string> arguments;

    annotations["format"] = "minidump";       // 设置生成 minidump
    arguments.push_back("--no-rate-limit");   // 禁用崩溃速率限制

    base::FilePath db(db_path);
    base::FilePath handler(handler_path);

    // 初始化崩溃报告数据库
    database = crashpad::CrashReportDatabase::Initialize(db);
    if (database == nullptr || database->GetSettings() == NULL) {
        return false;
    }
    
    // 启用自动上传 (如果提供了服务器URL)
    database->GetSettings()->SetUploadsEnabled(true);

    // 启动 crashpad_handler 进程
    CrashpadClient client;
    return client.StartHandler(handler,          // handler_path
                               db,               // 数据库路径
                               db,               // 指标目录(可与数据库路径相同)
                               url,              // 上传服务器 URL (可选)
                               annotations,      // 附加信息
                               arguments,        // 启动参数
                               false,            // 重启进程
                               false,            // 异步启动
                               std::vector<base::FilePath>()); // 附件
}

int main(int argc, char** argv) {
    // 初始化 Crashpad
    std::string upload_url("http://your-crash-report-server.com"); // 你的崩溃报告服务器地址,留空则仅本地保存
    std::wstring handler_path(L"path/to/crashpad_handler.exe");    // 指向 crashpad_handler.exe
    std::wstring db_path(L"path/to/crash/db");                     // 存放 dump 的目录

    if (!startCrashHandler(upload_url, handler_path, db_path)) {
        // 处理初始化失败
        return -1;
    }

    // ... 你的应用程序逻辑 ...

    // 模拟一个崩溃来测试 (例如,空指针解引用)
    // int* p = nullptr;
    // *p = 123;

    return 0;
}
在 Qt 项目中的配置

如果你使用 Qt,需要在 .pro 文件中添加相应的配置:

复制代码
INCLUDEPATH += $$PWD/crashpad/include/
INCLUDEPATH += $$PWD/crashpad/include/mini_chromium/
INCLUDEPATH += $$PWD/crashpad/include/util/

LIBS += -L$$PWD/crashpad/lib/ -lbase -lclient -lutil -lcommon
LIBS += -lAdvapi32

🧪 测试与调试

测试崩溃捕获
  1. 在你的代码中模拟一个崩溃,例如解引用空指针。

    cpp 复制代码
    int* p = nullptr;
    *p = 123;
  2. 编译并运行程序。

  3. 程序崩溃后,检查你设置的 db_path 目录下是否生成了 .dmp 文件。

分析 Dump 文件

要分析生成的 .dmp 文件,你可以:

  • 使用 Visual Studio 直接打开 .dmp 文件。确保你的 .pdb 符号文件与编译崩溃程序时生成的符号文件一致,这样 Visual Studio 才能解析出准确的调用堆栈。
  • 使用 WinDbg 等工具进行分析。

💡 注意事项与高级配置

  • 路径问题 :确保 crashpad_handler.exe 的路径正确,并且应用程序有权限访问它以及写入崩溃数据库目录 (db_path)。
  • 符号文件 :发布程序时,请妥善保管对应版本的 .pdb 符号文件,这是后续调试定位崩溃问题的关键。
  • 避免符号冲突 :在某些情况下,如果包含 Windows 头文件前未定义 NOMINMAX,可能会遇到 "no_init_all"C2589 等编译错误。在包含 Windows 头文件之前定义 NOMINMAX 可以避免这些问题。
  • 上传服务器 :如果你设置了 upload_url,Crashpad 会尝试将崩溃报告上传到该服务器。你需要搭建相应的服务来接收和处理这些报告。如果不需要上传,可以将 upload_url 留空。
  • 运行时库匹配 :确保你的项目和 Crashpad 库使用相同的运行时库(如 /MD/MT),以避免链接冲突。

💎 总结

通过以上步骤,应该成功地在 Windows 下为你的应用程序配置好了 Crashpad 崩溃捕获。简单来说,核心步骤就是:编译 Crashpad 库 → 在项目中引入头文件和库 → 在程序启动时初始化 Crashpad 客户端并指定 crashpad_handler 路径和崩溃数据存储路径

参考引用:

1.How to Build Google Crashpad

2.windows系统下使用crashpad为vs2019项目在崩溃时生成dump文件(步骤超详细)

3.windows下dump捕获 crashpad

相关推荐
炮院李教员4 小时前
TortoiseSVN 右键不显示的解决方法
windows
Larry_Yanan4 小时前
QML学习笔记(五十)QML与C++交互:QML中单例C++对象
开发语言·c++·笔记·qt·学习·ui·交互
im_AMBER4 小时前
算法笔记 09
c语言·数据结构·c++·笔记·学习·算法·排序算法
竹竹零4 小时前
JacksonUtil--序列化与反序列化
java·开发语言·windows
catoop5 小时前
在 Windows 中基于 WSL 子系统 Ubuntu 安装配置 conda 示例
windows·ubuntu·conda
SweetCode5 小时前
C++ 实现大数加法
开发语言·c++·算法
stay_alive.5 小时前
C++ 四种类型转换
开发语言·c++
卡提西亚5 小时前
C++笔记-9-三目运算符和switch语句
c++·笔记
CodeWizard~6 小时前
AtCoder Beginner Contest 430赛后补题
c++·算法·图论