如何诊断这些PHP代码覆盖率分段和zend_mm_堆损坏错误

如何诊断这些PHP代码覆盖率分段和zend_mm_堆损坏错误,php,segmentation-fault,code-coverage,Php,Segmentation Fault,Code Coverage,我一直很高兴在我的Ubuntu机器上编写代码。这是一台有很多公羊的结实机器。我当时正在编写4个新类,编写和运行单元测试。在某种程度上,我注意到,虽然单元测试完成得很好,但代码覆盖率却不高 在“生成代码覆盖率报告…等等”消息之后,我会收到一条消息,说zend_mm_heap已损坏。我尝试了一些修复,包括:在php.ini(apache2和cli)中设置output\u buffering=On,以及从代码中删除对unset()的调用。(我继续阅读,以便可能需要这些固定的) 现在,我似乎在zend_

我一直很高兴在我的Ubuntu机器上编写代码。这是一台有很多公羊的结实机器。我当时正在编写4个新类,编写和运行单元测试。在某种程度上,我注意到,虽然单元测试完成得很好,但代码覆盖率却不高

在“生成代码覆盖率报告…等等”消息之后,我会收到一条消息,说zend_mm_heap已损坏。我尝试了一些修复,包括:在php.ini(apache2和cli)中设置
output\u buffering=On
,以及从代码中删除对
unset()
的调用。(我继续阅读,以便可能需要这些固定的)

现在,我似乎在zend_-mm之间交替。。。错误和分段错误(核心转储)错误,无论我做什么。我对测试进行注释,直到我缩小我认为导致问题的测试范围,并在那里进行一些更改,直到我得到一个干净的运行。然后,我将取消对所有测试的注释,结果发现错误仍然存在

有什么想法吗?我可以使用什么工具或方法来收集更多信息

我使用的是PHP_CodeCoverage 1.2.6、PHP5.3.10-1ubuntu3.5、PHPUnit 3.7.9

编辑:


顺便说一下,我找不到任何核心转储文件。已经从我的两个物理磁盘的根目录进行了搜索,但没有成功。我已经阅读了core上的man条目,包括core转储没有创建文件的可能原因,但我认为这些都不适用。

我最近也遇到了同样的问题。这似乎是PHP垃圾收集的一个问题。在phpunit运行期间禁用垃圾收集解决了我的问题

加:

到您的
php.ini
文件,或通过以下命令行:

phpunit -d zend.enable_gc=0

我也遇到了同样的问题,并尝试使用zend.enable_gc=0,但是phpunit内存不足。为了解决这个问题,我基本上修改了我的覆盖范围白名单,使之更加细化。因此,在phpunit.xml中,我之前有这样一个:

<filter>
    <whitelist>
        <directory suffix=".php">../application/src</directory>
    </whitelist>
</filter>

../application/src
我把它改成这样:

<filter>
    <whitelist>
        <directory suffix=".php">../application/src/module1</directory>
        <directory suffix=".php">../application/src/module2</directory>
        <directory suffix=".php">../application/src/module3</directory>
        <exclude>
            <directory>../application/src/module1/views</directory>
        </exclude>

    </whitelist>
</filter>

../application/src/module1
../application/src/module2
../application/src/module3
../application/src/module1/views

因此,只需将过滤器限制为只包含真正重要的文件。这仍然是一个bug,但目前我认为,限制覆盖率计算中考虑的文件数量将有助于防止此类问题。

在使用代码覆盖率运行PhpUnit时,有时很难理解分段错误。我在PHP7.0.5和2个版本的PhpUnit上出现了分段错误

最后,在我的案例中跟踪到问题之后,类似这样的事情导致了分割错误

$x = doSomething(doSomethingElse());
将内部函数提取为变量,如下所示:

$y = doSomethingElse();
$x = doSomething($y);

解决了这个问题。上面的这段代码当然是简化的代码,但您应该理解,有时代码中没有真正的错误,但您应该修改它,使PhpUnit的代码覆盖范围适用于您的代码。

至于获得更多信息,您可以尝试gdb回溯。
gdb php
。从gdb内部,
运行/usr/bin/phpunit
。当phpunit segfaults进入
bt
。更多关于布莱克的信息,这是一个很大的帮助。如果我能给你一枚奖章,我会的!哇!这节省了我很多时间!但是,去除gc的内存安全吗?@很可能不是。我想这只是开发环境中的一个临时解决方法,所以内存安全并不是什么大问题。这是我最近遇到的完全相同问题的解决方案。你知道为什么会这样吗?我的意思是,这显然是100%有效的代码。这怎么可能失败呢?我的情况与此类似:将“DB::raw”(“$this->getCommentCountQuery()->toSql()”)更改为“DB::raw”($comment\u count\u query)作为fl\u comments\u count”)“``问题已得到解决。这一次的另一个案例是从``返回SnappyPdf::loadHTML($this->->renderHTML())``到``$html=$this->renderHTML();返回SnappyPdf::loadHTML($html)```
$y = doSomethingElse();
$x = doSomething($y);