我怎样才能找出我的程序中哪个线程崩溃了?

How can I find out which thread crashed inside my program?

考虑以下程序:

#include <atomic>
#include <thread>
#include <iostream>
#include <string>
#include <windows.h>

std::atomic<int> crashId;

void threadFunction(int id) {
    while (id != crashId) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    int* p = nullptr;
    *p = id;
}

int main() {
    std::thread t1(&threadFunction, 1);
    std::thread t2(&threadFunction, 1);
    int id;
    std::cin >> id;
    crashId = id;
    while (true) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

我启动程序(以发布模式构建)并去吃午饭。当我回来时,一位同事输入了 1 或 2。

如何找出崩溃的线程?或者我怎样才能重写程序以便第二天就能找到它?

我尝试了事件查看器。这似乎只向我的 .exe 报告了进程 ID 和文件路径。

如果我将每个线程 运行 放在单独的 .dll 中,我会在事件查看器日志中看到吗?

在 Windows 上,您可以设置与程序名称关联的注册表项,以便在发生崩溃时生成转储文件

示例说明here and here(我总是建议生成“完整”故障转储)

有了崩溃转储,您可以将其加载到 Windbg 等工具中,甚至 Visual Studio 以观察调用堆栈并查看变量值。

您可能需要将 PDB 文件与工具的符号路径中的 EXE 相关联,才能查看函数和变量名称。优化的构建通常更难调试,但有一些编译器开关可以生成更好(和更大)的 PDB 文件,使零售调试几乎与 non-optimzed 构建一样好。