Linux下web程序通常有两种执行方式
1. 直接由httpd进程处理,如module方式的php
2. 由httpd子进程产生的cgi程序处理,httpd子进程只负责输入输出
一般来讲,观察程序的运行时行为使用strace,对于命令行程序非常好使,但是对于一个web请求,就不太好下手了,因为那么多httpd子进程,请求落在哪个httpd子进程是不好说的,不过一般可以有两种技巧:
1. 通过httpd.conf限制httpd的最大子进程数为1,这样就指定由这个httpd子进程处理了,直接strace -p pid 就行了
2. 使用命令
pids=`ps aux | grep httpd | awk 'BEGIN {str="";}{str = str "-p " $2 " ";} END {print str}' `; strace -o httpd.strace $pids
跟踪所有的httpd子进程
上面两种方法对于第一种执行方式比较好使,但是对于第二种执行方式就不好使了,因为产生的那个子进程是转瞬即逝的,你根本来不及看见它,所以看看下面两种技巧:
1. 还是用strace,不是捕获不到pid吗?实际上是可以的,别忘了strace的 -f -F 参数,只要看住父进程,子进程就甭想跑掉,命令如下:
pids=`ps aux | grep httpd | awk 'BEGIN {str="";}{str = str "-p " $2 " ";} END {print str}' `; strace -f -F -o httpd.strace $pids
也就比上面的命令多个 -f -F
2. 不要通过web调试了,太低级趣味了,直接在命令行strace吧,那参数怎么传呢?哦,这就介绍一下:
例如:cgi程序abc.cgi 执行时需要get参数a、b、c,而且限制访问ip为10.10.10.10,写脚本debug_abc.sh如下:
export REQUEST_METHOD=GET
export REMOTE_ADDR=10.10.10.10
export QUERY_STRING="a=A&b=B&c=C"
./abc.cgi
保存,现在:strace sh debug_abc.sh 看看。