我花了几个小时试图调试一个使用 exec() 运行 c 模拟的 php 脚本。在到处抛出 stderr 打印消息后,我终于发现潜在的问题是使用 sprintf() 打印一个太小的字符数组的目录路径。
我猜这是一个分段错误,但我实际上从未看到 shell 错误消息说"分段错误"。当我更改分配大小时,一切正常。
我一直在将 stderr 输出重定向到日志文件,该日志文件从 fprintf(stderr,"...")获取了所有消息;但它没有收到任何 shell 错误消息。
命令是这样的
exec("$cmd 2>> $logFile & $PROCFILE 1 $ipaddr $! 2>> $logFile", $output, $rv);
$cmd运行 c 模拟,$PROCFILE运行第二个 c 程序,该程序接受三个参数(1、$ipaddr 和 $!)。在我修复分配大小问题之前,php 脚本只会停止执行$cmd模拟并继续下一行(即在 exec() 语句之后)。php 文件中的下一行是
if(rv!=0){handle error}
但这也没有抓住问题所在。
我一直以为我遇到了权限错误。如何让 exec() 显示外壳错误?或者这是使用"&"同时运行两个程序的结果?
当程序死亡时,"分段错误"消息来自shell,而不是来自程序。重定向仅适用于程序的输出,不适用于 shell 的输出。消息应放入 $output 变量中。如果$rv是0并且$output中没有任何内容,我怀疑你对发生的事情是错误的。我建议您通过编写一个简单的测试程序来验证这一点:
kill(0, SIGSEGV);
顺便说一句,你为什么不使用snprintf()
,所以你不能首先得到缓冲区溢出?