93 lines
2.8 KiB
C++
93 lines
2.8 KiB
C++
|
#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
|