Add better error checks and race condition protection in crash handling

This commit is contained in:
baldurk
2019-09-16 11:18:30 +01:00
parent 01fb4fd793
commit 9463cdf785
4 changed files with 97 additions and 50 deletions
+10 -8
View File
@@ -383,18 +383,20 @@ int main(int argc, char *argv[])
if(!crashReportPath.isEmpty())
{
QFile f(crashReportPath);
QVariantMap json;
if(f.exists() && f.open(QIODevice::ReadOnly | QIODevice::Text))
{
QVariantMap json = JSONToVariant(QString::fromUtf8(f.readAll()));
QFile f(crashReportPath);
if(json.contains(lit("report")))
{
CrashDialog dialog(config, json);
if(f.exists() && f.open(QIODevice::ReadOnly | QIODevice::Text))
json = JSONToVariant(QString::fromUtf8(f.readAll()));
}
RDDialog::show(&dialog);
}
if(json.contains(lit("report")))
{
CrashDialog dialog(config, json);
RDDialog::show(&dialog);
}
}
else
+4 -1
View File
@@ -63,8 +63,11 @@ public:
GetTempPathW(MAX_PATH - 1, tempPath);
std::wstring dumpFolder = tempPath;
dumpFolder += L"RenderDoc/dumps";
dumpFolder += L"RenderDoc";
CreateDirectoryW(dumpFolder.c_str(), NULL);
dumpFolder += L"\\dumps";
CreateDirectoryW(dumpFolder.c_str(), NULL);
MINIDUMP_TYPE dumpType = MINIDUMP_TYPE(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory);
+6 -1
View File
@@ -288,7 +288,12 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CreateBugReport(const char
mz_zip_archive zip;
RDCEraseEl(zip);
report = FileIO::GetTempFolderFilename() + "/renderdoc_report.zip";
if(report.empty())
{
char filename[128] = {};
StringFormat::sntimef(filename, 127, "/renderdoc_report_%H%M%S.zip");
report = FileIO::GetTempFolderFilename() + filename;
}
FileIO::Delete(report.c_str());
+77 -40
View File
@@ -455,8 +455,13 @@ struct CrashHandlerCommand : public Command
GetTempPathW(MAX_PATH - 1, tempPath);
std::wstring dumpFolder = tempPath;
dumpFolder += L"RenderDoc/dumps";
// create each parent directory separately, and use \\s
dumpFolder += L"RenderDoc";
CreateDirectoryW(dumpFolder.c_str(), NULL);
dumpFolder += L"\\dumps";
CreateDirectoryW(dumpFolder.c_str(), NULL);
crashServer =
@@ -535,7 +540,31 @@ struct CrashHandlerCommand : public Command
}
}
rdcstr reportPath;
FILETIME filetime = {};
SYSTEMTIME systime = {};
GetSystemTimeAsFileTime(&filetime);
FileTimeToSystemTime(&filetime, &systime);
uint32_t milliseconds = 0;
milliseconds += systime.wHour;
milliseconds *= 60;
milliseconds += systime.wMinute;
milliseconds *= 60;
milliseconds += systime.wSecond;
milliseconds *= 1000;
milliseconds += systime.wMilliseconds;
rdcstr dumpId;
char base62[63] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
while(milliseconds > 0)
{
char c = base62[milliseconds % 63];
dumpId.push_back(base62[milliseconds % 62]);
milliseconds /= 62;
}
rdcstr reportPath = conv(dumpFolder) + "\\" + dumpId + ".zip";
RENDERDOC_CreateBugReport(conv(wlogpath).c_str(), conv(wdump).c_str(), reportPath);
@@ -547,52 +576,60 @@ struct CrashHandlerCommand : public Command
report += "}\n";
{
std::wstring destjson = dumpFolder + L"\\report.json";
std::wstring destjson = dumpFolder + L"\\" + conv(dumpId) + L".json";
FILE *f = NULL;
_wfopen_s(&f, destjson.c_str(), L"w");
fputs(report.c_str(), f);
fclose(f);
wchar_t *paramsAlloc = new wchar_t[512];
ZeroMemory(paramsAlloc, sizeof(wchar_t) * 512);
GetModuleFileNameW(NULL, paramsAlloc, 511);
wchar_t *lastSlash = wcsrchr(paramsAlloc, '\\');
if(lastSlash)
*lastSlash = 0;
std::wstring exepath = paramsAlloc;
ZeroMemory(paramsAlloc, sizeof(wchar_t) * 512);
_snwprintf_s(paramsAlloc, 511, 511, L"%s/qrenderdoc.exe --crash %s", exepath.c_str(),
destjson.c_str());
PROCESS_INFORMATION pi;
STARTUPINFOW si;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
BOOL success =
CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, exepath.c_str(), &si, &pi);
if(success && pi.hProcess)
if(!f)
{
WaitForSingleObject(pi.hProcess, INFINITE);
OutputDebugStringA("Coudln't open report json");
}
else
{
fputs(report.c_str(), f);
fclose(f);
if(pi.hProcess)
CloseHandle(pi.hProcess);
if(pi.hThread)
CloseHandle(pi.hThread);
wchar_t *paramsAlloc = new wchar_t[512];
std::wstring wreport = conv(std::string(report));
ZeroMemory(paramsAlloc, sizeof(wchar_t) * 512);
DeleteFileW(wreport.c_str());
GetModuleFileNameW(NULL, paramsAlloc, 511);
wchar_t *lastSlash = wcsrchr(paramsAlloc, '\\');
if(lastSlash)
*lastSlash = 0;
std::wstring exepath = paramsAlloc;
ZeroMemory(paramsAlloc, sizeof(wchar_t) * 512);
_snwprintf_s(paramsAlloc, 511, 511, L"%s/qrenderdoc.exe --crash %s", exepath.c_str(),
destjson.c_str());
PROCESS_INFORMATION pi;
STARTUPINFOW si;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
BOOL success = CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL,
exepath.c_str(), &si, &pi);
if(success && pi.hProcess)
{
WaitForSingleObject(pi.hProcess, INFINITE);
}
if(pi.hProcess)
CloseHandle(pi.hProcess);
if(pi.hThread)
CloseHandle(pi.hThread);
std::wstring wreport = conv(reportPath);
DeleteFileW(wreport.c_str());
DeleteFileW(destjson.c_str());
}
}
}