【发布时间】:2010-11-02 01:25:18
【问题描述】:
我有一个有趣的(至少对我而言)问题:在某些情况下,我无法找到可靠且可移植地获取孙进程信息的方法。我有一个应用程序AllTray,我试图在某些奇怪的情况下开始工作,其中它的子进程产生一个孩子然后死去。 AllTray 的工作本质上是将应用程序停靠在任务托盘上,任务托盘(通常)被指定为 AllTray 调用的命令行(即alltray xterm 将启动 xterm,并在 AllTray 中对其进行管理)。
大多数 GUI 软件在它下都可以正常运行。它在其窗口上设置了_NET_WM_PID 属性(或小部件库),一切都很好,因为_NET_WM_PID == fork()ed 孩子。然而,在某些情况下(例如运行oowriter,或编写为在 KDE 下运行的软件,如 K3b),AllTray 运行的子进程是一个包装器,它是一个 shell 脚本(如 OO.o 的情况)或一个奇怪的程序,fork()s 和 exec()s 本身并有效地将自身背景化,因为父进程很早就死了。
我的想法是不获取我的子进程,以便在进程表中保留我孙子的父进程 ID,以便我可以通过从下到上遍历家谱来将它们链接回我.但是,这不起作用:一旦我的子进程死亡并变成僵尸,系统就会认为我的孙子进程是孤儿,init 会采用它。至少在 Linux 2.6 和 NetBSD 上似乎是这样。我想这可能是常态,而 POSIX 似乎并没有明确规定是这种情况,所以我希望相反。
由于这种方法行不通,我考虑使用LD_PRELOAD 并拦截我的子进程对fork() 的调用,并将信息传递回我的父进程。但是,我担心它不会像理想的解决方案那样可移植,因为不同的系统对于动态链接器如何执行LD_PRELOAD 之类的操作有不同的规则。如果没有帮助程序库也是 setuid 或 setgid,它就不适用于 setuid/setgid GUI 应用程序,至少在 Linux 系统上是这样。一般来说,这对我来说是个坏主意,而且感觉很hackish。
所以,我希望有人知道如何做到这一点,或者如果依赖像 LD_PRELOAD 这样的机制的想法真的是我唯一没有修补内核的选择(这是 不会发生)。
【问题讨论】: