diff --git a/qrenderdoc/Code/qrenderdoc.cpp b/qrenderdoc/Code/qrenderdoc.cpp index e4749303f..413f9d84f 100644 --- a/qrenderdoc/Code/qrenderdoc.cpp +++ b/qrenderdoc/Code/qrenderdoc.cpp @@ -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 diff --git a/renderdoc/core/crash_handler.h b/renderdoc/core/crash_handler.h index b4e96dd75..7eb01dbaf 100644 --- a/renderdoc/core/crash_handler.h +++ b/renderdoc/core/crash_handler.h @@ -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); diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index 6d522b970..ab66bb3ab 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -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()); diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index a5560fef8..fda279021 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -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()); + } } }