how-to-use/cpp/error/cpp_err.cpp

93 lines
2.8 KiB
C++
Raw Permalink Normal View History

2024-03-08 14:01:18 +08:00
#include "cpp_err.h"
#include <string>
#ifdef _MSC_VER
#include "windows.h"
#include "DbgHelp.h"
#endif
void stackoverflow()
{
// 1.线程栈空间有上限: windows 默认:1MB,Linux默认 2MB。
// 2.当前线程占用栈空间大小:线程函数调用堆栈中各个函数占用的栈空间总和。
// 3.哪些对象占用了栈空间:
// (1)函数局部变量
// (2)调用函数的参数
// 4.常见引发栈溢出的原因:
// (1)递归太深
// (2)局部变量占用太大
// (3)switch-case case分支过多。
// (4)死循环调用
// 5.发生线程栈溢出时,VS可能直接退出,无法看到调用堆栈,可以使用WinDBG查看。
}
#ifdef _MSC_VER
int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers, const std::string& dump_dir)
{
// 定义函数指针
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;
HMODULE hDbgHelp = LoadLibrary("DbgHelp.dll");
if (NULL == hDbgHelp)
{
return EXCEPTION_CONTINUE_EXECUTION;
}
pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if (NULL == pfnMiniDumpWriteDump)
{
FreeLibrary(hDbgHelp);
return EXCEPTION_CONTINUE_EXECUTION;
}
// 创建 dmp 文件
char path_buffer[512]{};
char szVersion[] = "DumpDemo_v1.0";
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
std::snprintf(path_buffer, sizeof(path_buffer), "%s\\%s-%04d%02d%02d-%02d%02d%02d.dmp", dump_dir.c_str(),
szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
HANDLE hDumpFile = CreateFile(path_buffer, 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);
FreeLibrary(hDbgHelp);
return EXCEPTION_EXECUTE_HANDLER;
}
LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
// 这里做一些异常的过滤或提示
if (IsDebuggerPresent())
{
return EXCEPTION_CONTINUE_SEARCH;
}
return GenerateMiniDump(lpExceptionInfo, "D:\\");
}
// windows cpp 崩溃使用 windbg 调试
void use_windbg()
{
SetUnhandledExceptionFilter(ExceptionFilter);
}
#endif