通常在一个终端执行一个耗时很长的程序时,我们使用nohup来执行,避免终端关闭时程序退出; 程序退出多半是程序需要输出,而输出终端已经不存在了,导致IO错误。
下面观察了一下test.php 的程序在终端执行的情况:
<?php
while(1) {
echo "hello world\n";
sleep(5);
}
————————————–
在一个终端启动程序:
php test.php
# ltrace -p 19197
write(1, "hello world\n", 12) = 12
fflush(0x8515c0) = 0
sleep(5) = 0
write(1, "hello world\n", 12) = 12
…
在另一个终端使用gdb调试该进程,当前一个终端关闭时,程序因写失败而进入函数php_handle_aborted_connection ; 这里将连接状态设置为abort,然后检查是否忽略连接abort,因为我设置为不忽略,所以程序退出了。修改程序,添加 ignore_user_abort(true); 这样的话,终端退出后,进程也不会退出了。但是,我们就又发现另外一个现象,这时候使用ltrace跟踪时,write调用没有了,因为php使用函数:php_ub_body_write_no_header 输出时,检查了变量output_globals.disable_output, 而该变量在发现连接断开时被置为 1 , 所以再也看不到输出了。
奇怪的是,使用ltrace跟踪的使用,命名是使用write系统调用输出的,gdb调试时,给write函数设置断点,居然不能拦住????