From c735a307508ca978ba890be6aee6cc1d139fe6ff Mon Sep 17 00:00:00 2001 From: Cody Northrop Date: Tue, 27 Jun 2017 13:24:50 -0600 Subject: [PATCH] os: Update LaunchProcess to consume all stdout before checking stderr For commands that write to stdout multiple times before writing stderr, the second ReadFile would hang indefinitely. This was seen using "adb pull" with a sufficiently large APK (~20MB). --- renderdoc/os/posix/posix_process.cpp | 7 +++++-- renderdoc/os/win32/win32_process.cpp | 20 ++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/renderdoc/os/posix/posix_process.cpp b/renderdoc/os/posix/posix_process.cpp index 1f848f5bc..74025e41c 100644 --- a/renderdoc/os/posix/posix_process.cpp +++ b/renderdoc/os/posix/posix_process.cpp @@ -455,18 +455,21 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c result->strStderror = ""; ssize_t stdoutRead, stderrRead; + char chBuf[4096]; do { - char chBuf[1000]; stdoutRead = read(stdoutPipe[0], chBuf, sizeof(chBuf)); if(stdoutRead > 0) result->strStdout += string(chBuf, stdoutRead); + } while(stdoutRead > 0); + do + { stderrRead = read(stderrPipe[0], chBuf, sizeof(chBuf)); if(stderrRead > 0) result->strStderror += string(chBuf, stderrRead); - } while(stdoutRead > 0 || stderrRead > 0); + } while(stderrRead > 0); // Close read ends. close(stdoutPipe[0]); diff --git a/renderdoc/os/win32/win32_process.cpp b/renderdoc/os/win32/win32_process.cpp index a9fe9d0fc..c0863baf8 100644 --- a/renderdoc/os/win32/win32_process.cpp +++ b/renderdoc/os/win32/win32_process.cpp @@ -925,20 +925,28 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c { result->strStdout = ""; result->strStderror = ""; + + char chBuf[4096]; + DWORD dwOutputRead, dwErrorRead; + BOOL success = FALSE; + string s; for(;;) { - char chBuf[1000]; - DWORD dwOutputRead, dwErrorRead; - - BOOL success = ReadFile(hChildStdOutput_Rd, chBuf, sizeof(chBuf), &dwOutputRead, NULL); - string s(chBuf, dwOutputRead); + success = ReadFile(hChildStdOutput_Rd, chBuf, sizeof(chBuf), &dwOutputRead, NULL); + s = string(chBuf, dwOutputRead); result->strStdout += s; + if(!success && !dwOutputRead) + break; + } + + for(;;) + { success = ReadFile(hChildStdError_Rd, chBuf, sizeof(chBuf), &dwErrorRead, NULL); s = string(chBuf, dwErrorRead); result->strStderror += s; - if(!success && !dwOutputRead && !dwErrorRead) + if(!success && !dwErrorRead) break; }