1. 首先从github 下载源代码 crashrpt3
2. 用CMake Gui 编译成vs studio 工程文件
2.1 点击 config 按钮
2.2 依次点击 Generate 按钮、Open Project 按钮.之后vs 2022 会打开编译好的sln工程文件
3.全选解决方案里面的所有项目,设置C++语言标准,我这里设置是最新C++,即启用的是C++23的标准
根据实际需要调整32位/64位和字符串集合
设置CrashRpt工程属性
添加: /Zc:__cplusplus 选项,这个是解决 “__cplusplus 这个宏上,可以看到它的值展开为:199711L”
接着修改3个文件,因为C++20弃用了一些C++17的语法,导致编译失败,所以需要进行调整:
1. 修改CrashHandler.h 只有一处要修改
struct ThreadExceptionHandlers
{
ThreadExceptionHandlers()
{
m_prevTerm = NULL;
m_prevUnexp = NULL;
m_prevSigFPE = NULL;
m_prevSigILL = NULL;
m_prevSigSEGV = NULL;
}
terminate_handler m_prevTerm; // Previous terminate handler
//unexpected_handler m_prevUnexp; <-----这条语句修改为一下:
//
#if __cplusplus < 202002L
unexpected_handler m_prevUnexp; // Previous unexpected handler (only for C++ versions < C++20)
#else
std::terminate_handler m_prevUnexp; // Using terminate_handler as a substitute in C++20 and later
#endif
// unexpected_handler m_prevUnexp; // Previous unexpected handler
void (__cdecl *m_prevSigFPE)(int); // Previous FPE handler
void (__cdecl *m_prevSigILL)(int); // Previous SIGILL handler
void (__cdecl *m_prevSigSEGV)(int); // Previous illegal storage access handler
};
2.修改 CrashHandler.cpp 有两处要修改
int CCrashHandler::SetThreadExceptionHandlers(DWORD dwFlags)
{
...//省略
if(dwFlags&CR_INST_UNEXPECTED_HANDLER)
{
// Catch unexpected() calls.
// In a multithreaded environment, unexpected functions are maintained
// separately for each thread. Each new thread needs to install its own
// unexpected function. Thus, each thread is in charge of its own unexpected handling.
// http://msdn.microsoft.com/en-us/library/h46t5b69.aspx
//handlers.m_prevUnexp = set_unexpected(UnexpectedHandler); <-----这条语句修改成以下:
/
#if __cplusplus < 202002L
handlers.m_prevUnexp = set_unexpected(UnexpectedHandler);
#else
handlers.m_prevUnexp = std::set_terminate(UnexpectedHandler);
#endif
/
}
}
int CCrashHandler::UnSetThreadExceptionHandlers()
{
...//省略
if(handlers->m_prevUnexp!=NULL)
{
//set_unexpected(handlers->m_prevUnexp); <-----这条语句修改成以下:
#if __cplusplus < 202002L
set_unexpected(handlers->m_prevUnexp);
#else
set_terminate(handlers->m_prevUnexp);
#endif
}
}
3.修改 CrashRpt.cpp 只有一处要修改
crEmulateCrash(unsigned ExceptionType) noexcept(false)
{
...//省略
case CR_CPP_UNEXPECTED_CALL:
{
// Call unexpected
//
// unexpected(); <-----这条语句修改成以下:
//
#if __cplusplus < 202002L
unexpected();
#else
std::terminate();
#endif
//
}
break;
}
修改完上述3个文件之后,工程就可以在C++20及其以上编译成功了.
修复一个使用中的bug:生成的crashrpt.xml和crashdump.dmp中的修改时间是UTC时间非本地时间
在 CrashSender工程里面的 ErrorReportSender.cpp
//crashdump.dmp的修改时间改成本地时间
BOOL CErrorReportSender::CreateMiniDump()
{
...//省略
cleanup:
/
//change to local time
if (hFile != INVALID_HANDLE_VALUE) {
SYSTEMTIME localTime;
GetLocalTime(&localTime);
FILETIME ft;
SystemTimeToFileTime(&localTime, &ft);
SetFileTime(hFile, &ft, &ft, &ft);
}
/
<----------加上上述代码
// Close file
if(hFile)
CloseHandle(hFile);
}
///crashrpt.xml 修改时间改成本地时间
void CErrorReportSender::AddElemToXML(CString sName, CString sValue, TiXmlNode* root)
{
...//省略
cleanup:
//if(f)
// fclose(f);
//<---改为如下代码:
///
if(f)
{
fclose(f);
HANDLE hFile = CreateFile(
sFileName,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
// Get the current local time
SYSTEMTIME localTime;
GetLocalTime(&localTime);
// Convert local time to FILETIME
FILETIME fileTime;
SystemTimeToFileTime(&localTime, &fileTime);
// Set the modification time of the file
SetFileTime(hFile, NULL, NULL, &fileTime);
// Close the file handle
CloseHandle(hFile);
}
}
//
}