Bootstrap

Window以及Ubuntu下的core dump调试方法

Ubuntu系统

1.修改系统dump文件大小

#查看大小
ulimit -a
#修改为不限制大小
ulimit -c unlimited

2.修改系统dump文件命名方式

sudo sysctl -w kernel.core_pattern=core.%p

3.运行程序,遇到异常会生成core dump文件

./Detection

4.利用GDB工具分析core dump文件,定位异常代码

gdb ./Detection core.3795

Windows系统

1.对于Qt工程需要在pro文件中增加配置生产pdb文件

CONFIG += force_debug_info
CONFIG += separate_debug_info

2.添加转储函数helper.h头文件,并在程序开头调用异常捕获函数

3.运行程序,遇到异常会生成core dump文件

4.使用Visual Studio打开dump文件,定位异常代码位置

#include "helper.h"
//...
SetUnhandledExceptionFilter(ExceptionFilter);

5.ProcDump工具

使用微软官方的ProcDump工具生成dump文件。参考:https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump

附录

Windows下转存dump文件的代码

//helper.h
#pragma once

#include <QCoreApplication>
#include <QDateTime>
#include <tchar.h>
#include <Windows.h>
#include <DbgHelp.h>
#include <QString>
#include <QDebug>

int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers)
{
    // 定义函数指针
    typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
        HANDLE,
        DWORD,
        HANDLE,
        MINIDUMP_TYPE,
        PMINIDUMP_EXCEPTION_INFORMATION,
        PMINIDUMP_USER_STREAM_INFORMATION,
        PMINIDUMP_CALLBACK_INFORMATION
        );
    // 从 "DbgHelp.dll" 库中获取 "MiniDumpWriteDump" 函数
    MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
    QString libraryName = "DbgHelp.dll";
    HMODULE hDbgHelp = LoadLibraryW((LPCWSTR)(libraryName.toStdWString().c_str()));

    if (NULL == hDbgHelp)
    {
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");

    if (NULL == pfnMiniDumpWriteDump)
    {
        FreeLibrary(hDbgHelp);
        return EXCEPTION_CONTINUE_EXECUTION;
    }

    // 创建 dmp 文件
    QString strDir = QCoreApplication::applicationDirPath();
    QString strPath = strDir+QString("/DumpFile_%1.dmp").arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"));

    qDebug() << strPath;
    HANDLE hDumpFile = CreateFileW((LPCWSTR)(strPath.toStdWString().c_str()), GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
    if (INVALID_HANDLE_VALUE == hDumpFile)
    {
        FreeLibrary(hDbgHelp);
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    // 写入 dmp 文件
    MINIDUMP_EXCEPTION_INFORMATION expParam;
    expParam.ThreadId = GetCurrentThreadId();
    expParam.ExceptionPointers = pExceptionPointers;
    expParam.ClientPointers = FALSE;
    pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
        hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &expParam : NULL), NULL, NULL);
    // 释放文件
    CloseHandle(hDumpFile);b 
    FreeLibrary(hDbgHelp);
    return EXCEPTION_EXECUTE_HANDLER;
}

LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
    // 这里做一些异常的过滤或提示
    if (IsDebuggerPresent()) {
        return EXCEPTION_CONTINUE_SEARCH;
    }
    return GenerateMiniDump(lpExceptionInfo);
}
;