为什么在多次或仅一次调用 CreateProcess 时会恰好泄漏两个句柄?
Why do I leak exactly two handles when calling CreateProcess multiple times or just once?
根据 GetProcessHandleCount
,我在调用 CreateProcess
时丢失了两个句柄。请看下面的最小示例,它将创建一个子进程。在创建子进程之前,检查句柄的数量。然后关闭 PROCESS_INFORMATION
结构中返回的子进程句柄,然后再次计算句柄。我得到 2
句柄的差异 - 有人知道为什么吗?
同样有趣:如果我在下面示例的 for 循环中创建多个子进程,我也会 "leak" 正好两个句柄。
编辑:请注意,在 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;
}
UKMonkey 是对的,它将加载 apphelp.dll
,这将打开两个句柄:
查看以下两个屏幕截图,显示加载/打开的 dll 和句柄:
通过调用 LoadLibrary
加载 dll 本身将打开 SESSION MANAGER
的句柄,第一次调用 CreateProcess
将打开 Custom Locale
的句柄。
根据 GetProcessHandleCount
,我在调用 CreateProcess
时丢失了两个句柄。请看下面的最小示例,它将创建一个子进程。在创建子进程之前,检查句柄的数量。然后关闭 PROCESS_INFORMATION
结构中返回的子进程句柄,然后再次计算句柄。我得到 2
句柄的差异 - 有人知道为什么吗?
同样有趣:如果我在下面示例的 for 循环中创建多个子进程,我也会 "leak" 正好两个句柄。
编辑:请注意,在 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;
}
UKMonkey 是对的,它将加载 apphelp.dll
,这将打开两个句柄:
查看以下两个屏幕截图,显示加载/打开的 dll 和句柄:
通过调用 LoadLibrary
加载 dll 本身将打开 SESSION MANAGER
的句柄,第一次调用 CreateProcess
将打开 Custom Locale
的句柄。