2016-10-25 76 views
1

根據GetProcessHandleCount我在撥打CreateProcess時失去兩個手柄。請看下面的最小例子,它將創建一個子進程。在創建子進程之前,檢查句柄的數量。然後關閉在PROCESS_INFORMATION結構中返回的子進程句柄,然後再次對句柄進行計數。我得到了2句柄的區別 - 有沒有人知道爲什麼?另外有趣的是:如果我在下面的示例中的for循環中創建了多個子進程,那麼我也會「精確地」泄漏兩個句柄。爲什麼我在多次調用CreateProcess或僅調用一次時會泄漏兩個句柄?

編輯:請注意,在StartupInformation結構中沒有句柄被返回,所以沒有什麼可以關閉的。

有人可以向我解釋這兩個手柄的區別嗎?

#include <windows.h> 
#include <tchar.h> 
#include <iostream> 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::wstring commandLine = L"C:\\windows\\system32\\cmd.exe"; 

    BOOL closedHT = FALSE; 
    BOOL closedHP = FALSE; 
    BOOL createdProcess = FALSE; 

    // Count handles before creating child processes: 
    HANDLE hCurrent = GetCurrentProcess(); 
    DWORD hCountBefore = 0; 
    ::GetProcessHandleCount(hCurrent, &hCountBefore); 

    // Create one child-processes: 
    for (size_t i = 0; i < 1; i++) 
    { 
     STARTUPINFO startupInfo; 
     ::ZeroMemory(&startupInfo, sizeof(startupInfo)); 

     PROCESS_INFORMATION procInfo; 
     ::ZeroMemory(&procInfo, sizeof(procInfo)); 

     createdProcess = ::CreateProcess(NULL, (LPWSTR)commandLine.c_str(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &procInfo); 
     closedHP = ::CloseHandle(procInfo.hProcess); 
     closedHT = ::CloseHandle(procInfo.hThread); 
    } 

    // And calculate the difference of handles: 
    DWORD hCountAfter = 0; 
    ::GetProcessHandleCount(hCurrent, &hCountAfter); 
    DWORD diff = hCountAfter - hCountBefore; 

    if (createdProcess && closedHP && closedHT && diff != 0) 
    { 
     std::wcout << L"lost handles??: " << diff << std::endl; 
    } 
    else 
    { 
     std::wcout << L"Nothing got lost" << std::endl; 
    } 

    return 0; 
} 
+0

很明顯'CreateProcess'會導致一些按需處理被打開。只要處理次數不會持續增加,它就不是真正的泄漏。 – Erik

+2

我猜想CreateProcess會打開一個未關閉的dll(或2)。 – UKMonkey

+0

@UKMonkey:就是這樣!它會加載'apphelp.dll',這將打開兩個句柄。 – erg

回答

0

UKMonkey是正確的,它會加載apphelp.dll將打開兩個把手:

參見下面的兩個截圖,示出了DLL和處理加載/打開的:

DDLs and handles before calling CreateProcess

DLLS and handles after calling CreateProcess

通過調用LoadLibrary加載dll本身將會l打開SESSION MANAGER的手柄,第一次撥打CreateProcess將打開手柄至Custom Locale

相關問題