调试Perl模块时,为何Perl调试器执行R(重载)命令会挂起?
Perl调试器执行R命令后挂起问题(SLES12 SP5 + Perl 5.18.2)
在SLES12 SP5的Perl 5.18.2环境中,调试模块时执行R命令后Perl调试器会出现挂起问题,复现步骤如下:
% perl -Ilib -mSimple -d -e1 Loading DB routines from perl5db.pl version 1.39_10 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. Simple::CODE(0x215fa60)(lib/Simple.pm:19): 19: die "bad\n" 20: if (something); DB<1> n Simple::CODE(0x1e6fde0)(lib/Simple.pm:4): 4: require 5.018_000; DB<1> R Warning: some settings and command-line options may be lost! Loading DB routines from perl5db.pl version 1.39_10 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. ^C^C^C^C^Z [2]+ Stopped perl -Ilib -mSimple -d -e1
该问题可复现于任意模块,以下为用于演示的Simple.pm代码:
% cat lib/Simple.pm #!/usr/bin/perl package Simple; require 5.018_000; use strict; use warnings; sub something { use integer; my $result = 0; return $result; } UNITCHECK { $DB::single = 1; die "bad\n" if (something); } 1;
问题分析
通过strace追踪发现,Perl实际从STDIN(文件描述符0)读取行。在执行R命令时用gdb附加到进程(测试环境为openSUSE Leap 15.4),得到以下输出:
Continuing. process 2427 is executing new program: /usr/bin/perl [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". ^C Program received signal SIGINT, Interrupt. 0x00007ff83747071e in read () from /lib64/libpthread.so.0 Missing separate debuginfos, use: zypper install perl-base-debuginfo-5.26.1-150300.17.14.1.x86_64 (gdb) bt #0 0x00007ff83747071e in read () from /lib64/libpthread.so.0 #1 0x000055933f42576d in PerlIOUnix_read () #2 0x000055933f428ba8 in PerlIOBuf_fill () #3 0x000055933f4272a8 in Perl_PerlIO_fill () #4 0x000055933f428aa0 in PerlIOBase_read () #5 0x000055933f42aa78 in PerlIO_getc () #6 0x000055933f3c0595 in Perl_sv_gets () #7 0x000055933f326d37 in Perl_lex_next_chunk () #8 0x000055933f330bd3 in Perl_yylex () #9 0x000055933f34489d in Perl_yyparse () #10 0x000055933f318617 in perl_parse () #11 0x000055933f2f0e5c in main ()
后续测试
Perl虽在读取STDIN但不显示调试器提示符,在Linux系统中按下Ctrl+D后,得到以下输出:
Debugged program terminated. Use q to quit or R to restart, use o inhibit_exit to avoid stopping after program termination, h q, h R or h o to get additional info.
此时本应可以输入Perl调试器命令,但实际Perl未处理任何输入,说明调试器处于挂起状态。
疑点排查
进一步测试发现,Perl调试器确实在读取输入,按下Ctrl+D可终止该无响应状态,且从重启后到按下Ctrl+D期间输入的命令未被实时处理,而是在输入EOF后才被回显:
DB<0> R Warning: some settings and command-line options may be lost! Loading DB routines from perl5db.pl version 1.39_10 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. l ghgh <<<<<<<<< ^D (EOF) entered here main::(-:1): l main::(-:2): ghgh
从strace输出中看到open("/lib64/libreadline.so.6", O_RDONLY|O_CLOEXEC) = 3,因此怀疑libreadline库可能与该问题有关。
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

