在Mac上编译需要Xcode 12.2
rendererdoc是开源的代码,今天调试一个32位的程序,发现始终无法capture frames
网络异常,图片无法展示
|
API:None
,既然无法得知原因,就直接看代码吧
下载后的rendererdoc代码windows直接编译通过了,因为我看文档说64位的renderdoc可以调试32/64的program,所以直接选择
网络异常,图片无法展示
|
运行后直接报这个错:
网络异常,图片无法展示
|
追溯源代码发现:
wchar_t renderdocPath[MAX_PATH] = {0}; // renderdocpath的值是由renderdoc.dll的路径决定的 GetModuleFileNameW(GetModuleHandleA(STRINGIZE(RDOC_DLL_FILE) ".dll"), &renderdocPath[0], MAX_PATH - 1); // 如果是32位的program,则使用32位的renderdoc,反之使用64位 #if ENABLE(RDOC_X64) //... #else // ... #endif wchar_t *paramsAlloc = new wchar_t[2048]; // paramsAlloc的值来自renderdocPath的值 _snwprintf_s( paramsAlloc, 2047, 2047, L"\"%ls\" capaltbit --pid=%u --capfile=\"%ls\" --debuglog=\"%ls\" --capopts=\"%hs\"", renderdocPath, pid, wcapturefile.c_str(), wdebugLogfile.c_str(), optstr.c_str()); // 变量来自paramsAlloc wchar_t *commandLine = paramsAlloc; // 这里的retValue=0导致的,原因是commandLine指向了一个不存在的renderrdoc.exe文件,导致程序报错 BOOL retValue = CreateProcessW(NULL, commandLine, &pSec, &tSec, false, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, NULL, NULL, &si, &pi); if (!retValue) { RDResult result; // 提示无法运行32位的rendererCmd捕获32位的程序 SET_ERROR_RESULT( result, ResultCode::InternalError, "Can't run 32-bit renderdoccmd to capture 32-bit program." "If this is a locally built RenderDoc you must build both 32-bit and 64-bit versions."); CloseHandle(hProcess); return {result, 0}; } 复制代码
development环境好像又严格的32/64区分,运行程序时32位的,只能乖乖选择
网络异常,图片无法展示
|
运行后正常了,下一步就是看API:None时怎么会是
网络异常,图片无法展示
|
renderdoc\qrenderdoc\Windows\Dialogs\LiveCapture.cpp
extern "C" RENDERDOC_API ITargetControl *RENDERDOC_CC RENDERDOC_CreateTargetControl( const rdcstr &URL, uint32_t ident, const rdcstr &clientName, bool forceConnection) { rdcstr host = "localhost"; if(!URL.empty()) host = URL; rdcstr deviceID = host; uint16_t port = ident & 0xffff; IDeviceProtocolHandler *protocol = RenderDoc::Inst().GetDeviceProtocol(deviceID); if(protocol) { deviceID = protocol->GetDeviceID(deviceID); host = protocol->RemapHostname(deviceID); if(host.empty()) return NULL; port = protocol->RemapPort(deviceID, port); } else { int32_t idx = deviceID.indexOf(':'); if(idx > 0) { host = deviceID.substr(0, idx); port = atoi(deviceID.substr(idx + 1).c_str()) & 0xffff; } } if(port == 0) return NULL; // 通过socket建立链接 Network::Socket *sock = Network::CreateClientSocket(host, port, 750); if(sock == NULL) return NULL; TargetControl *remote = new TargetControl(sock, clientName, forceConnection != 0); if(remote->Connected()) return remote; delete remote; return NULL; } void LiveCapture::connectionThreadEntry() { // 创建了链接 ITargetControl *conn = RENDERDOC_CreateTargetControl(m_Hostname, m_RemoteIdent, GetSystemUsername(), true); // 从链接池中获取数据 while (conn && conn->Connected()) { TargetControlMessage msg = conn->ReceiveMessage(); if (msg.type == TargetControlMessageType::RegisterAPI) // 消息类型 { QString api = msg.apiUse.name; bool presenting = msg.apiUse.presenting; bool supported = msg.apiUse.supported; GUIInvoke::call(this, [this, api, presenting, supported]() { m_APIs[api] = APIStatus(presenting, supported); if(presenting && supported) { ui->triggerImmediateCapture->setEnabled(true); ui->triggerDelayedCapture->setEnabled(true); ui->queueCap->setEnabled(true); } updateAPIStatus(); }); } } } // 更新API状态 void LiveCapture::updateAPIStatus() { QString apiStatus; bool nonpresenting = false; // add any fully working APIs first in the list. for (QString api : m_APIs.keys()) { if (m_APIs[api].supported && m_APIs[api].presenting) apiStatus += lit(", <b>%1 (Active)</b>").arg(api); } // then add any problem APIs for (QString api : m_APIs.keys()) { if (!m_APIs[api].supported) { apiStatus += tr(", %1 (Unsupported)").arg(api); } else if (!m_APIs[api].presenting) { apiStatus += tr(", %1 (Not Presenting)").arg(api); nonpresenting = true; } } ui->apiStatus->setText(apiStatus); } 复制代码
从以上代码看出来,UI界面时在监听net数据,接下来排查方向就是寻找TargetControlMessageType::RegisterAPI
的发送源头 renderdoc\renderdoc\core\target_control.cpp