【问题标题】:Can the child process affect parent process' environment?子进程会影响父进程的环境吗?
【发布时间】:2012-03-10 18:24:31
【问题描述】:

子继承父环境”是什么意思?通过复制整个环境来继承,还是通过接收指向同一环境的指针来继承(以某种方式)?


这是我的场景:

  1. 我有一个正在运行的进程P 有自己的环境(变量)
  2. 在某些时候,P 执行 fork
  3. if-statement(也就是子进程C)的0-clone 中,执行execv
  4. 两个进程继续独立运行。

因此,在某个时刻,应用程序停止正常工作。原因是 - “破碎”的环境。

有趣的是,两个环境都发生了变化。当我启动父进程并执行时

$ cat /proc/PID/environ

对于两者 - 父进程和进程,一切都很好。几个小时后,应用程序停止工作,当我再次执行上面的行(检查环境)时,两者都已更改并且缺少很多环境变量 - 只有标准变量存在(如PWDHOMEUSER 等)。

这怎么可能?问题可能出在哪里——在孩子身上还是在父母身上?


编辑:感谢大家的回答,我 +1,因为他们都是正确的(@caf、@Saphrosit 和 @R..)。这个问题的原因真的很傻。。

所有环境变量都放在/etc/profile 中,在登录后执行(那个..我不知道)。

好吧,看来问题是在重新启动机器时发生的。因此,在启动时,应用程序再次启动,但 /etc/profile/ 执行/读取。这会导致不良行为。这就是问题在手动重启时消失的原因 - 一旦登录root(通过ssh),读取来自/etc/profiles的环境变量,并且当重新启动父进程时(通过root),它是一切都很好 - 环境变量是继承的。

愚蠢的错误。

【问题讨论】:

  • 您是否曾从父母那里致电waitwaitpid?否则,子进程终止后仍将是僵尸进程。
  • 疯狂猜测 - 可能两者都死了并重新启动,环境错误?如果是这样,您会看到 PID 已更改。
  • @ugoren - 有可能,我还找不到有关此的信息。但即使是这样——所有的环境变量都设置在/etc/profile中,它们并没有在shell中手动导出..所以,即使是这样,我也无法想象有什么东西可以“破坏”环境如此糟糕跨度>
  • @BlagovestBuyukliev - 是的,父级中有一个waitpid。但这有多重要?我的意思是,这会以某种方式影响环境吗? (我知道我需要阅读更多关于守护进程的信息,我正在研究这个:))

标签: c++ c unix process environment-variables


【解决方案1】:

如果没有更多细节,这个问题真的几乎不可能回答,但我还是要试一试?

你确定调用fork时环境的内容确实有效吗?当然,您可能损坏了内存,但父级此时已经获得并缓存了它关心的变量的副本,并且只有稍后它在尝试重新获取一个时才会中断。如果是这样的话,孩子的环境也应该被打破,但孩子可能不在乎……

如果这不是问题,那么工作系统上剩下的唯一可能性似乎是父级正在重新启动而您不知道,或者父级在forking 之后损坏了自己的环境。

否则,也许您在损坏的设备上有一个交换分区,并且当它被换回时环境正在被换出和损坏......?

【讨论】:

  • 我刚刚想通了。感谢您的努力(+1)。我将编辑我的问题以添加有关导致问题的原因的解释。是的,问题出在fork.. 之前的恶劣环境中,是由真正的错误造成的。如果您有兴趣,请查看我的编辑:)(我会在 5 分钟内发布)
【解决方案2】:

...或者两者兼而有之?

子项从其父环境的副本开始,因此不会影响其父环境。所以我不认为孩子改变了父亲的环境,但也许是父亲改变了自己。

如果不知道程序到底做了什么,很难说问题出在哪里......

【讨论】:

  • 是的,我知道我没有显示任何代码,但应用程序非常复杂,我不能只提取 3 行并说 - “这会破坏某些东西”。我正在寻找一些可能导致这种情况的提示。
【解决方案3】:

子级在fork() 的时刻继承了父级环境的副本。任何一个过程中对环境的后续更改都不会影响另一个过程。

改变这一点的唯一方法是做一些非常奇怪的事情,比如将环境放在MAP_SHARED 区域,或者使用ptrace()。不过,如果你做了这样的事情,你会知道的。

【讨论】:

  • 嗯,我没有这样的东西.. 那么是什么导致cat /proc/PID/environ 的输出不同.. 也许,两个进程同时发生了一些事情?有趣的是,当我仅“重新启动”子进程时,问题仍然存在(正如预期的那样,因为它继承了父进程的环境),当我重新启动父进程时,一切都开始正常工作。所有变量都放在/etc/profile 中,它们不是在shell 中手动导出的。有什么想法吗?
  • 我会接受你的回答,因为它直接回答了我的问题(在“场景”描述之前)。我将编辑我的问题以添加导致问题的解释。谢谢。
  • ptrace() 怎么办?更新环境变量时不涉及系统调用。
  • @Barmar:PTRACE_POKEDATA可以直接改变被跟踪进程的内存,可以用来改变环境。
  • 啊,我假设你说的是父母被动地复制孩子的环境变化,而不是孩子故意改变父母。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多