首页
社区
课程
招聘
[旧帖] Windows核心编程5版4章4.2.7节关于子进程id有矛盾问题 0.00雪花
发表于: 2012-7-29 20:30 1678

[旧帖] Windows核心编程5版4章4.2.7节关于子进程id有矛盾问题 0.00雪花

2012-7-29 20:30
1678
99页 "说明"里的文字
说明
应用程序运行期间,必须关闭到子进程及其主线程的句柄,以避免资源泄漏。当然,系统会在你的进程终止后自动清理这种泄漏。但是,如果是一个编写精妙的软件,肯定会在进程不再需要访问一个子进程及其主线程的时候,显式地调用CloseHandle来关闭这些句柄。忘记关闭这些句柄是开发人员最容易犯的错误之一。

应该是建议大家创建子进程后,就用CloseHandle关闭子进程和主线程句柄

但100页 4.3节的向上的一段文字说
要保证一个进程或线程ID不被重用,惟一的办法就是保证进程或线程对象不被销毁。为此,在创建了一个新进程或线程之后,不关闭到这些对象的句柄即可。等到应用程序不再使用ID的时候,再调用CloseHandle来释放内核对象。但是,一旦调用了CloseHandle,再使用或依赖进程ID就不安全了。这一点务必牢记

就是说保证id不被重用的唯一方法就是不关闭句柄.

那这就有疑问了,如果CloseHandle关闭了进程或者主线程句柄, 系统开新进程的id会使用原来的那个么?????
如果会,那不是乱套了,资源管理器里出现2个相同的进程的应用程序,
如过不会,那不是作者自己说的前后矛盾了.

请朋友们指点,谢谢。

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
首先告诉你的是,书上讲的是对的。
如果CloseHandle关闭了进程或者主线程句柄, 系统开新进程的id可能会使用原来的那个,
这也就是说,如果closeHandle了进程或主线程句柄,并且该进程或线程已经退出,那么,他们对应的id也就不再有效,这是如果有新的进程或线程产生,那么使用的id就很有可能是这个id。
比如,某个进程的id是4321,当这个进程退出,并且父进程closehandle了子进程句柄,那么这是的4321就不再有任何意义。此时如果有第二个进程产生,那么这个进程id可是4322,也可能是4321.
你所说的资源管理器运行2个相同名字的进程,因为进程都再运行,因此它的id是有效而且是唯一的。只要当其中一个进程不再运行,并且调用它的父进程也closehandle了,那么它的id才被收回,也即此id不再有效。
总之,这个进程或线程id有效,需要2个条件:1.进程或线程仍然在运行。2.产生该进程或线程的父亲必须closehandle。此时进程或线程对象才真正从内核中销毁。对象销毁了,那么代码对象的唯一id也就随之不再有效。
2012-7-30 09:34
0
雪    币: 120
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢.

你说的怎么变成2个条件了(和书上矛盾了)
引用的第2段文字明明是只有一个条件,只要关闭了句柄, id就无效了,内核对象引用就减1了(当然内核对象本身不一定销毁)

还有
我写代码做过试验的
CreateProcess(.....,&pi);  打开一个notepad.exe (没有手动按窗口X关闭)
然后立刻关闭句柄
ret1 = CloseHandle(pi.ThreadHandle);
ret2 = CloseHandle(pi.ProcessHandle);

ret1 ret2都是TRUE,也就是句柄成功销毁

如果按照你说的, 其实id没有失效(因为notepad.exe窗口没关闭), 绝对不会被重用。-- 这样的话,我也就没有疑问了 -- 资源管理里不会出现2个相同id的进程
如果按照书上说的, id就已经失效了,可以被重用 -- 这样的话, 就可能出现2个相同的id哦 ???

另外,
我还发现一个问题, 连续调用个关闭句柄2次,第2次的时候会引发crt异常,真奇怪
也就是这样写
ret1 = CloseHandle(pi.ThreadHandle);
ret2 = CloseHandle(pi.ProcessHandle);
ret1 = CloseHandle(pi.ThreadHandle);   //<--crt异常,调试弹出非法框
ret2 = CloseHandle(pi.ProcessHandle);  //<--crt异常,调试弹出非法框
按照以往的实际代码经验,句柄参数不管是NULL,还是乱七八遭的数据,只要内核找不到这个数值(即认为非法句炳), 则CloseHandle返回FALSE, 并不会异常的。
朋友们能解释下为什么会出现crt异常么, 谢谢了
2012-7-30 11:14
0
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
1.我说的并与书上讲的并不矛盾。进程id有没有失效,其实就看内核对象还是否存在。如果存在,其id就有效,否则其id就没有意义。那么内核对象有没有销毁,内核对象引用有没有减到0。CreateProcess,内核对象引用增加了两次。closehandle减了一次,进程退出又减了1次。故此时做了销毁,id也不复存在。
2.closehandle无效句柄,将可能会引起异常。我个人的做法是:CloseHandle后,置句柄值为NULL。就像指针一样处理的,如:
CloseHanle(hDevice);
hDevice = NULL;
2012-7-30 14:07
0
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
补充一下:
关闭句柄后,置空的另一个好处,是避免关闭另一个并不希望关闭的句柄值。
2012-7-30 14:14
0
雪    币: 120
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢,虽然理解你的意思,但总感觉怪怪的

我在这里也发了个帖子
http://topic.csdn.net/u/20120730/15/d8fe4846-e82f-4cac-be91-268e466ec600.html?seed=1706241246&r=79270958#r_79270958
2012-7-30 19:40
0
游客
登录 | 注册 方可回帖
返回
//