[Perl]交互调试mod_perl
应该很多人都在为mod_perl的调试方法发愁吧。通常只能使用print,或者输出到syslog中, 但都需要猜测错误位置并添加相应的日志输出,然后重启服务器,刷新,看结果…… 虽然使用Apache::Reload能减少重启服务器的麻烦,但Apache::Reload用多了就会出错,而必须重启, 何况打日志总不像交互式调试器方便。
mod_perl
的官方文档中写明了如何使用调试器来调试,
不过这个方法在RHEL4下似乎不太好用(自己编译mod_perl
的同学就应该没这个问题)。
查看了一下,原来RHEL4自带的mod_perl
是 mod_perl-1.99_16-4
,
而在官方的mod_perl
的下载页面上最高版本只有 1 系的 1.30 和2系的2.0.4,并没有所谓的1.99版。
看这个mod_perl-1.99
的内容,应该是1系和2系的混合体吧。
Apache::DB这个包与mod_perl-1.99
不兼容,于是就无法正常调试了。
不过办法总是有的——自己改!方法如下。
-
安装Apache::DB。去CPAN搜索Apache::DB安装即可。这里的例子使用的是Apache-DB-0.13。 安装方法不用多说,直接 perl Makefile.PL && make && make install。
-
修改Apache::DB:
打开/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/Apache/DB.pm,注释掉72-74行:
69 else { 70 if (ref $r) { 71 $SIG{INT} = \&DB::catch; 72 # $r->register_cleanup(sub { 73 # $SIG{INT} = \&DB::ApacheSIGINT(); 74 # }); 75 } 76 }
-
然后修改httpd.conf,加载调试模块:
<IfDefine PERLDB> <Perl> use Apache::DB (); Apache::DB->init; </Perl> <Location /> PerlFixupHandler Apache::DB </Location> </IfDefine> <IfDefine !PERLDB> PerlInitHandler Apache::Reload </IfDefine>
这里定义了一个环境变量PERLDB,这个变量存在时即启动Apache::DB供交互调试使用, 不存在则加载Apache::Reload用于通常的开发。
-
停止Apache
# /etc/init.d/httpd stop
-
以调试方式启动Apache
# httpd -X -D PERLDB [notice] Apache::DB initialized in child 11135
-
从浏览器访问要调试的页面。这时即可进入调试器。
Loading DB routines from perl5db.pl version 1.27 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. DB<1>
然后就可以使用尽情地调试了。
一般的调试方法都是,先 use 你要调试的模块,然后设置断点,执行,再单步。 写成命令就是:
DB<1> use Your::Module; # 先use一下避免添加断点时找不到函数(不是必须的)
DB<2> b Your::Module::foo; # 在foo函数开始处设置断点
DB<3> c # 执行到断点
DB<4> n # 单步执行(要step in就用s)
DB<5> x $bar; # 查看变量的详细内容
最后,想结束调试时,再开个终端然后 killall httpd
就行了。