【发布时间】:2015-06-18 09:48:16
【问题描述】:
我在这样的 Linux Ubuntu 14.04-LTS 机器上有一个开发树,具有三个相同的分支:
main -+-- leonardo --- project --- htdocs -+- panel --- index.php
| |
| +- config.php
|
+-- federico --- project --- htdocs -+- panel --- index.php
| |
| +- config.php
|
+-- carlo ------ project --- htdocs -+- panel --- index.php
| |
| +- config.php
..... (you get my drift).
既没有软链接也没有硬链接。 config.php 文件在 svn-ignore 中并且在所有分支之间是不同的
有一个 Apache 服务器,每个开发人员都有一个虚拟主机,所以我可以在 http://leonardo.project.local 或 Federico 的 http://federico.project.local 上查看我的开发版本。
在调查当前的怪异时,这两个文件是:
<?php // this is panel/index.php
echo "I am " . __FILE__ . "\n";
echo "I will include " . realpath('../config.php') . "\n";
require_once '../config.php';
<?php // this is config.php
echo "I am " . __FILE__ . "\n";
exit();
当然,预期的输出是:
I am leonardo/project/htdocs/panel/index.php
I will include /var/www/main/leonardo/project/htdocs/config.php
I am leonardo/project/htdocs/config.php
但实际输出是:
I am leonardo/project/htdocs/panel/index.php
I will include /var/www/main/leonardo/project/htdocs/config.php
I am federico/project/htdocs/config.php
另外一个奇怪的地方是
echo "I will include " . realpath('../config.php') . "\n";
require_once realpath('../config.php');
有效。
TL;DR require_once 和 realpath 不同意 '../config.php' 的实际位置。
真正奇怪的是我没有看到如何在leonardo/project/htdocs/panel/ 中运行的脚本可以知道关于federico/project/htdocs/config.php;它应该向上四个目录,然后探索很多子目录。
我几乎开始怀疑这可能与文件系统甚至内核相关。
文件系统是ext4,内核是3.13.0-55-generic #92-Ubuntu SMP Sun Jun 14 18:32:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux。该机器是最新 VMware Workstation 上的虚拟 x64。
检查
- PHP 的
include_path只包括.和/usr/local/php5/pear。 - 如前所述,分支中没有文件是符号链接,所有相关文件的 inode 计数表明没有交叉链接。文件确实不同。
- 所有文件都确实存在,这不是“最后的包含”。
- 从命令行,在 leonardo...面板中,我运行“cat ../config.php”并得到我的 config.php,正如预期的那样。只有 PHP 会包含错误的文件。
- 重新启动 Apache(以防万一)无济于事。接下来我将尝试重新启动整个虚拟机,但要做到这一点,我需要冻结几个服务,这需要一段时间。
- 到昨天为止,一切都很糟糕(那时我不在这里)。在过去的三天里,没有系统更新,没有重新启动,甚至没有远程登录。现在正常运行时间为八天。
- 我是个白痴:我可以通过检查集成测试日志知道何时开始发生这种情况。已经要求他们,午餐后期待他们。
【问题讨论】:
-
某种操作码缓存在干扰?
-
系统确实使用
opcache。但我希望它已被 Apache 重新启动清除......?我对opcache操作不熟悉;它是否在某处使用共享内存或临时文件? -
@Blizz,我发现在集成测试开始出错之前,opcache.ini 文件已被有缺陷的同步脚本完全修改。在那之后,很容易发现血淋淋的细节。如果您发布有关该效果的答案,我很乐意用故事来扩展它并接受。事实证明,虽然重新启动 Apache 确实可以解决问题,但其他正在运行的脚本可能会再次破坏它们,太快以至于无法意识到它们已已修复。