Search code examples
c++winapiapplication-verifier

GetExitCodeProcess() throws first chance exception with Application Verifier


I use CreateProcess() to run an executable and call GetExitCodeProcess() at the end to get the exit code of the process. When I run it with application verifier I get a first chance exception. I've attached a picture of the log.enter image description here

Line number 1348 is line immediately after GetExitCodeProcess() call. I'm not very familiar with the log format so I'm asking is the exception thrown inside GetExitCodeProcess() in which case can I ignore it or am I doing something wrong in my code because it's pointing to the line after the call to GetExitCodeProcess()?

Edit: my code:

  if (!CreateProcess(
    NULL,  // it will get the app name from the next argument
    cString, // command line
    NULL,
    NULL,
    TRUE, // don't inherit handles
    CREATE_NO_WINDOW,
    NULL, // use environment of the calling process
    NULL, // use same current drive and directory as the calling process
    &siStartupInfo,
    &processInfo
    ))
  {
    // If process failed return error
    ...
  }

  // Close handles the passed to the child process.
  CloseHandle(hChildStd_ERR_Wr);
  CloseHandle(hChildStd_OUT_Wr);

  // Now read the std::out and std::err from child process and store them in strings to return
  DWORD dwRead;
  CHAR chBuf[4096];
  memset(chBuf, 0, 4096);
  BOOL bSuccess = FALSE;
  UString out = "", err = "";
  for (;;) {
    bSuccess=ReadFile( hChildStd_OUT_Rd, chBuf, 4096, &dwRead, NULL);
    if( ! bSuccess || dwRead == 0 )
      break;

    UString s(chBuf, dwRead);
    out += s;
  }
  dwRead = 0;
  memset(chBuf, 0, 4096);
  for (;;) {
    bSuccess=ReadFile( hChildStd_ERR_Rd, chBuf, 4096, &dwRead, NULL);
    if( ! bSuccess || dwRead == 0 )
      break;

    UString s(chBuf, dwRead);
    err.append(s);
  }

  consoleOutput = out;
  errorOutput = err;

  // Wait for the process to finish. Wait shouldn't happen before reading from pipes because
  // pipe writes happen only when someone is reading from them. For small amounts of data
  // this would not be a problem because the Pipe Manager buffer will consume data so the
  // write will succeed. But for large amounts of data, a reader must be present if not
  // the writer will wait indefinitely.
  WaitForSingleObject(processInfo.hProcess,INFINITE);

  // Close handles returned from Child process
  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);

  // Close read handles of the pipe
  CloseHandle(hChildStd_ERR_Rd);
  CloseHandle(hChildStd_OUT_Rd);

  // Get exit code for the process
  DWORD exitStat = 0;
  GetExitCodeProcess(processInfo.hProcess,&exitStat);

Solution

  • You are calling GetExitCodeProcess() after you have already closed the hProcess handle, so you are passing an invalid handle to it, and that is exactly what the verifier's error log is telling you:

    Invalid handle exception for current stack trace

    You need to leave hProcess open until after you are completely done using it, which includes passing it to GetExitCodeProcess().