【问题标题】:Why do my windows process handles stick around forever?为什么我的 Windows 进程句柄永远存在?
【发布时间】:2015-03-13 08:43:33
【问题描述】:

我可以在我的系统上找到与未显示在任务管理器中的进程相关联的进程 ID,因为它们很久以前就终止了,但也不会消失。为了识别它们,我使用这些系统调用:

static int
process_is_zombie(DWORD pid)
{
    DWORD exit_value;
    DWORD dwR;
    HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION|SYNCHRONIZE, FALSE, pid);
    if (!process_handle)
        return -1; // no handle attached to pid
    int exit_return = GetExitCodeProcess(process_handle, &exit_value);
    if (!exit_return)
        return -1; // GetExitCodeProcess failed, maybe no permission
    if(exit_value != STILL_ACTIVE)
        return 1; // got a handle, but process is definitely dead
    dwR = WaitForSingleObject(process_handle, 0);
    if(dwR == WAIT_OBJECT_0)
        return 1; // nope, it's really dead
    if(dwR == WAIT_TIMEOUT)
        return 0; // still alive!
    return -1; // WaitForSingleObject failed, maybe no permission
}

在我的系统任务管理器中显示 170 个正在运行的进程,但是当从 pid 0 扫描到 pid 700_000 时,我发现超过 150_000 个上述“僵尸”pid。使用进程资源管理器/任务管理器检查系统上活动进程的句柄并没有显示一个具有超过 2600 个句柄的进程,因此我的活动进程似乎都没有保留这些僵尸。

据我所知,这些 pid 之所以存在,是因为某些东西仍然可以控制它们。但是,我找不到有关如何找出这些进程 id 上究竟有什么句柄的信息。

这可能吗?如果有,怎么做?

【问题讨论】:

  • Process Explorer 可以显示每个进程打开的进程句柄。您可以从 Microsoft 的网站下载它。但是,退出 150,000 个进程并返回错误代码 STILL_ACTIVE 的可能性很小(不要介意它们还有句柄),所以我认为问题在于您没有将 is_zombie 初始化为零。
  • Process Explorer 在这种情况下没有帮助。此外,代码只是一个非常缩写的示例,现在我想起来我认为我在缩写它时犯了一个错误。我明天必须修改它。
  • 您需要发布能够实际演示问题的真实、有效的代码。进程资源管理器有什么问题?您必须一个一个地完成这些进程,但如果一个进程确实有 150k 个进程句柄打开,那会像拇指酸痛一样伸出来。实际上,首先要检查的是任务管理器;它可以显示每个进程总共打开了多少句柄。
  • 内核模式代码可以通过持有对对象的引用来保持对象活动,而无需实际创建句柄,请参阅 ObReferenceObject 和相关函数。不幸的是,如果发生这种情况,我不知道 Driver Verifier 是否会有所帮助。您可能需要查找受影响机器之间的共同因素。
  • 我发现更多 kd 挖掘进程没有句柄计数,但有指针​​计数,所有文献都表明来自内核模式软件,即驱动程序:HandleCount: 0 PointerCount: 74 这回答了我的问题.如果您愿意,可以将其作为答案插入,我会接受。

标签: c windows process


【解决方案1】:

进程对象(以及进程 ID)可以通过三种方式保持活动状态。首先,用户模式句柄;您通过检查进程资源管理器和/或任务管理器中的句柄计数来消除这种情况。其次,内核模式句柄,您使用内核调试器句柄转储消除了它。

最后一种可能性是内核模式引用(在 kd 中也称为“指针”)。这些是使用ObReferenceObject 和相关函数创建的。

长时间退出进程的指针计数为 74 向我表明该引用已多次泄漏。原则上,使用 kd 和 Driver Verifier,可以搜索指向对象的指针并确定哪个驱动程序拥有包含它们的内存。但是通过反复试验来识别有故障的驱动程序可能更实用。祝你好运!

【讨论】:

    猜你喜欢
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多