diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 7ca3a3ce6..d3dd9dc3f 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -2441,8 +2441,8 @@ void MainWindow::on_action_Resolve_Symbols_triggered() bool finished = false; m_Ctx.Replay().AsyncInvoke([this, &progress, &finished](IReplayController *) { - bool success = - m_Ctx.Replay().GetCaptureAccess()->InitResolver([&progress](float p) { progress = p; }); + bool success = m_Ctx.Replay().GetCaptureAccess()->InitResolver( + true, [&progress](float p) { progress = p; }); if(!success) { diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index d11de303a..b22590aed 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -1141,12 +1141,16 @@ necessary. This function blocks while trying to initialise callstack resolving, so it should be called on a separate thread. +:param bool interactive: ``True`` if missing symbols or other prompts should be resolved interactively. + If this is ``False``, the function will not interact or block forever on user interaction and will + always assume the input is effectively 'cancel' or empty. This may cause the symbol resolution to + fail. :param ProgressCallback progress: A callback that will be repeatedly called with an updated progress value for the resolver process. Can be ``None`` if no progress is desired. :return: ``True`` if the resolver successfully initialised, ``False`` if something went wrong. :rtype: ``bool`` )"); - virtual bool InitResolver(RENDERDOC_ProgressCallback progress) = 0; + virtual bool InitResolver(bool interactive, RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Retrieve the details of each stackframe in the provided callstack. diff --git a/renderdoc/core/remote_server.cpp b/renderdoc/core/remote_server.cpp index 4feeb5584..cc14d6cef 100644 --- a/renderdoc/core/remote_server.cpp +++ b/renderdoc/core/remote_server.cpp @@ -614,7 +614,7 @@ static void ActiveRemoteClientThread(ClientThread *threadData, } }); - resolver = Callstack::MakeResolver(buf.data(), buf.size(), + resolver = Callstack::MakeResolver(false, buf.data(), buf.size(), [&progress](float p) { progress = p; }); Threading::JoinThread(ticker); @@ -1943,7 +1943,7 @@ bool RemoteServer::HasCallstacks() return hasCallstacks; } -bool RemoteServer::InitResolver(RENDERDOC_ProgressCallback progress) +bool RemoteServer::InitResolver(bool interactive, RENDERDOC_ProgressCallback progress) { { WRITE_DATA_SCOPE(); diff --git a/renderdoc/core/remote_server.h b/renderdoc/core/remote_server.h index d88eaba6b..6fcdeca06 100644 --- a/renderdoc/core/remote_server.h +++ b/renderdoc/core/remote_server.h @@ -95,7 +95,7 @@ public: virtual bool HasCallstacks(); - virtual bool InitResolver(RENDERDOC_ProgressCallback progress); + virtual bool InitResolver(bool interactive, RENDERDOC_ProgressCallback progress); virtual rdcarray GetResolve(const rdcarray &callstack); diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 1a6dc82a9..5191bcaea 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -265,7 +265,8 @@ void Init(); Stackwalk *Collect(); Stackwalk *Create(); -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback); +StackResolver *MakeResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback); bool GetLoadedModules(byte *buf, size_t &size); }; // namespace Callstack diff --git a/renderdoc/os/posix/android/android_callstack.cpp b/renderdoc/os/posix/android/android_callstack.cpp index 52499c1a0..64da26454 100644 --- a/renderdoc/os/posix/android/android_callstack.cpp +++ b/renderdoc/os/posix/android/android_callstack.cpp @@ -77,7 +77,8 @@ bool GetLoadedModules(byte *buf, size_t &size) return true; } -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) +StackResolver *MakeResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress) { RDCERR("Callstack resolving not supported on Android."); return NULL; diff --git a/renderdoc/os/posix/apple/apple_callstack.cpp b/renderdoc/os/posix/apple/apple_callstack.cpp index 3bb44fd05..52b2e44b8 100644 --- a/renderdoc/os/posix/apple/apple_callstack.cpp +++ b/renderdoc/os/posix/apple/apple_callstack.cpp @@ -77,7 +77,8 @@ bool GetLoadedModules(byte *buf, size_t &size) return true; } -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) +StackResolver *MakeResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress) { RDCERR("Callstack resolving not supported on Apple."); return NULL; diff --git a/renderdoc/os/posix/ggp/ggp_callstack.cpp b/renderdoc/os/posix/ggp/ggp_callstack.cpp index 77dd1aeb0..ae23120b7 100644 --- a/renderdoc/os/posix/ggp/ggp_callstack.cpp +++ b/renderdoc/os/posix/ggp/ggp_callstack.cpp @@ -230,7 +230,8 @@ private: std::map m_Cache; }; -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) +StackResolver *MakeResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress) { // we look in the original locations for the files, we don't prompt if we can't // find the file, or the file doesn't have symbols (and we don't validate that diff --git a/renderdoc/os/posix/linux/linux_callstack.cpp b/renderdoc/os/posix/linux/linux_callstack.cpp index ba5f9d95c..50dee6b87 100644 --- a/renderdoc/os/posix/linux/linux_callstack.cpp +++ b/renderdoc/os/posix/linux/linux_callstack.cpp @@ -234,7 +234,8 @@ private: std::map m_Cache; }; -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) +StackResolver *MakeResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress) { // we look in the original locations for the files, we don't prompt if we can't // find the file, or the file doesn't have symbols (and we don't validate that diff --git a/renderdoc/os/win32/win32_callstack.cpp b/renderdoc/os/win32/win32_callstack.cpp index 237917ec2..2040bfc54 100644 --- a/renderdoc/os/win32/win32_callstack.cpp +++ b/renderdoc/os/win32/win32_callstack.cpp @@ -413,7 +413,8 @@ private: class Win32CallstackResolver : public Callstack::StackResolver { public: - Win32CallstackResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress); + Win32CallstackResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress); ~Win32CallstackResolver(); Callstack::AddressDetails GetAddr(uint64_t addr); @@ -719,7 +720,7 @@ rdcstr Win32CallstackResolver::pdbBrowse(rdcstr startingPoint) return StringFormat::Wide2UTF8(outBuf); } -Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, +Win32CallstackResolver::Win32CallstackResolver(bool interactive, byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) { rdcwstr configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini")); @@ -807,6 +808,10 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, { SAFE_RELEASE(source); + // can't manually locate msdia if we're non-interactive + if(!interactive) + return; + int ret = MessageBoxW(NULL, L"Couldn't initialise DIA - it may not be registered. " L"In VS2017 and above, DIA is not registered by default.\n\n" @@ -931,9 +936,9 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, { pdbName = get_dirname(defaultPdb) + "\\" + get_basename(defaultPdb); - // prompt for new pdbName, unless it's renderdoc or dbghelp + // prompt for new pdbName, unless it's renderdoc or dbghelp, or we're non-interactive if(pdbName.contains("renderdoc.") || pdbName.contains("dbghelp.") || - pdbName.contains("symsrv.")) + pdbName.contains("symsrv.") || !interactive) pdbName = ""; else pdbName = pdbBrowse(pdbName); @@ -975,6 +980,10 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, if(m.name.contains("renderdoc.") || m.name.contains("dbghelp.") || m.name.contains("symsrv.")) continue; + // if we're not interactive, just continue + if(!interactive) + continue; + rdcstr text = StringFormat::Fmt("Do you want to permanently ignore this file?\nPath: %s", m.name.c_str()); @@ -1085,7 +1094,8 @@ Stackwalk *Create() return new Win32Callstack(NULL, 0); } -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) +StackResolver *MakeResolver(bool interactive, byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress) { if(DBSize < 8 || memcmp(moduleDB, "WN32CALL", 8)) { @@ -1096,7 +1106,7 @@ StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCal // initialise dbghelp if we haven't already ::InitDbgHelp(); - return new Win32CallstackResolver(moduleDB, DBSize, progress); + return new Win32CallstackResolver(interactive, moduleDB, DBSize, progress); } bool GetLoadedModules(byte *buf, size_t &size) diff --git a/renderdoc/replay/capture_file.cpp b/renderdoc/replay/capture_file.cpp index fa4231851..1f62ccf62 100644 --- a/renderdoc/replay/capture_file.cpp +++ b/renderdoc/replay/capture_file.cpp @@ -169,7 +169,7 @@ public: bool WriteSection(const SectionProperties &props, const bytebuf &contents); bool HasCallstacks(); - bool InitResolver(RENDERDOC_ProgressCallback progress); + bool InitResolver(bool interactive, RENDERDOC_ProgressCallback progress); rdcarray GetResolve(const rdcarray &callstack); private: @@ -756,7 +756,7 @@ bool CaptureFile::HasCallstacks() return m_RDC && m_RDC->SectionIndex(SectionType::ResolveDatabase) >= 0; } -bool CaptureFile::InitResolver(RENDERDOC_ProgressCallback progress) +bool CaptureFile::InitResolver(bool interactive, RENDERDOC_ProgressCallback progress) { if(!HasCallstacks()) { @@ -789,7 +789,7 @@ bool CaptureFile::InitResolver(RENDERDOC_ProgressCallback progress) if(progress) progress(0.002f); - m_Resolver = Callstack::MakeResolver(buf.data(), buf.size(), progress); + m_Resolver = Callstack::MakeResolver(interactive, buf.data(), buf.size(), progress); if(!m_Resolver) {