前几天看到Microsoft收购了Sysinternals公司的消息,惊讶之余想起来更前些天Sysinternals的一个经典免费工具Process Explorer来调试Job Object遇到的问题。
Process Explorer
Process Explorer可以说是一个超级加强版的task manager,进程信息、内存使用、线程、Call Stack、handle的情况都可以查看。 是程序员调试程序,管理员预防病毒木马强大工具。 记得曾听过Dave Solomon的Windows Internals的培训,几乎他的所有关于系统内部情况的演示都是用process explorer来作的。
Job Object
Job Object 是Microsoft Windows上编程的一个概念, 它可以让你把一组进程作为一个单位进行管理。有一些你无法在进程级别控制的限制可以在Job Object上控制,它会应用到Job Object关联的每一个进程上。比如:最大工作集、最大user-mode执行时间、最多占用内存等等。 当Job Object的handle被关闭时,它所关联的所有进程都会被杀掉。这样就能提供一个类似砂箱沙箱的安全环境来执行一些不太可靠的代码。
遇到的问题
我们期待的是当那个Job Object的handle被关闭时,它所关联的进程都被杀掉,但是好像有点儿问题,作了一些修改后,我们用process explorer查看handle和进程的情况,发现handle的确被关闭了,但是那个进程就是不被杀掉,检查了各种参数都没找到原因。
转天,突然发现不开process explorer的时候就正常了!进程可以成功地被杀掉。突然想到,原来Process explorer为了能够查看每个handle的情况也会增加handle的reference,导致在CloseHandle的时候reference不是0,还没有真正关闭那个handle。
这不是Process Explorer的bug, 虽然在主进程中那个handle已经不见了,那个handle还被process explorer自己用着。
最后
应该早一些想到这个原因的。平时应该再好好读读Windows Internals。掌握一些系统的内部原理能够在你编程中遇到神奇问题的时候帮上大忙。

好东东啊