I'm just running this by the pm sanity check before
perlbugging it. The big questions are:
Is this a bug?
Is it still there in the development version?
Does this happen on old perl version with no
special "\0" handling?
perlrun says the -d:Foo=opt should work similarly
to -MDevel::Foo=opt but the =opt handling seems broken
(on 5.8.8)
$ echo 1 | perl -d:Foo=v
Can't find string terminator ";" anywhere before EOF.
$ echo 1 > a; perl -d:Foo=v a
Can't find string terminator ";" anywhere before EOF.
$ perl -d:Foo=v -e';1'
Number found where operator expected at -e line 1, near ";1"
(Might be a runaway multi-line ;; string starting on line 0)
(Missing operator before 1?)
syntax error at -e line 1, near ";1"
Execution of -e aborted due to compilation errors.
$ debugperl -DT -d:Foo=opt -e1
### 0:LEX_NORMAL/XSTATE "\n;"
### <== USE(ival=1)
### 0:LEX_KNOWNEXT/XTERM "split(/,/,q;\n"
### <== WORD(opval=null)
### 0:LEX_KNOWNEXT/XTERM "split(/,/,q;\n"
### <== WORD(opval=op_const) PV("Devel::Foo"\0)
### 0:LEX_NORMAL/XSTATE "split(/,/,q;\n"
### <== FUNC(ival=op_split)
### 0:LEX_NORMAL/XTERM "(/,/,q;\n"
### <== '('
### 0:LEX_NORMAL/XTERM "/,/,q;\n"
### <== PMFUNC(opval=op_match)
### 0:LEX_INTERPPUSH/XTERM ",q;\n"
### <== '('
### 0:LEX_INTERPCONCAT/XTERM ","
### 0:LEX_KNOWNEXT/XTERM ""
### <== THING(opval=op_const) PV(","\0)
### 0:LEX_INTERPSTART/XTERM ""
### <== ')'
### 0:LEX_NORMAL/XOPERATOR ",q;\n"
### <== ','
### 0:LEX_NORMAL/XTERM "q;\n"
Can't find string terminator ";" anywhere before EOF.
$ perl -d:Foo=v -e';);die 123;'
Can't locate Devel/Foo.pm in @INC (...)
$ echo 'sub DB::DB { }; 1' > lib/Devel/Foo.pm
$ perl -d:Foo=v -e';);die 123;'
123 at -e line 1.
$ cat lib/Devel/Foo.pm
package Devel::Foo;
sub DB::DB { }
sub import {
warn @{'::_<-e'};
}
1;
__DATA__
$ perl -d:Foo=v -e';);die 123;'
use Devel::Foo split(/,/,q;
;);die 123;
123 at -e line 1.
$ vi perl-5.8.8/perl.c +3089
case 'd':
forbid_setid("-d");
s++;
/* -dt indicates to the debugger that threads will be used */
if (*s == 't' && !isALNUM(s[1])) {
++s;
my_setenv("PERL5DB_THREADED", "1");
}
/* The following permits -d:Mod to accepts arguments following
+ an =
in the fashion that -MSome::Mod does. */
if (*s == ':' || *s == '=') {
const char *start;
SV *sv;
sv = newSVpv("use Devel::", 0);
start = ++s;
/* We now allow -d:Module=Foo,Bar */
while(isALNUM(*s) || *s==':') ++s;
if (*s != '=')
sv_catpv(sv, start);
else {
sv_catpvn(sv, start, s-start);
Perl_sv_catpvf(aTHX_ sv, " split(/,/,q%c%s%c)", 0, ++s
+, 0);
}
s += strlen(s);
my_setenv("PERL5DB", (char *)SvPV_nolen_const(sv));
}
if (!PL_perldb) {
PL_perldb = PERLDB_ALL;
init_debugger();
}
return s;
The equivalent bit for -M and -m processing (perl.c line 3232):
sv_catpvn(sv, start, s-start);
sv_catpv(sv, " split(/,/,q");
sv_catpvn(sv, "\0)", 1); /* Use NUL as q//-deli
+miter. */
sv_catpv(sv, ++s);
sv_catpvn(sv, "\0)", 2);
$ perl -d:Foo -MDevel::Foo=1 -e'die 123;'
use Devel::Foo;use Devel::Foo split(/,/,q1);
use Devel::Foo;use Devel::Foo split(/,/,q1);
123 at -e line 1.
Hmm, maybe this is related to sprintf and "\0" via Perl_sv_catpvf abov
+e
$ perl -d:Foo -MDevel::Foo=1 -e'die 123;' 2>&1 | od -c
0000000 u s e D e v e l : : F o o ;
+u
0000020 s e D e v e l : : F o o s
+p
0000040 l i t ( / , / , q \0 1 \0 ) ; \n
+u
0000060 s e D e v e l : : F o o ; u
+s
0000100 e D e v e l : : F o o s p
+l
0000120 i t ( / , / , q \0 1 \0 ) ; \n 1
+2
0000140 3 a t - e l i n e 1 . \
+n
0000160
$ perl -d:Foo=v -e';);die 123;' 2>&1 | od -c
0000000 u s e D e v e l : : F o o
+s
0000020 p l i t ( / , / , q ; \n ; ) ;
+d
0000040 i e 1 2 3 ; \n 1 2 3 a t
+-
0000060 e l i n e 1 . \n
0000072
$ grep -r -- -d: perl-5.8.8/t
perl-5.8.8/t/run/switchd.t: switches => [ '-Ilib', '-d:sw
+itchd' ],
I don't think this is currently tested
perl-5.8.8]$ diff -u ./t/run/switchd.t ./t/run/new_switchd.t
--- ./t/run/switchd.t 2003-05-24 17:49:13.000000000 +1000
+++ ./t/run/new_switchd.t 2007-10-07 15:49:52.000000000 +1000
@@ -7,7 +7,7 @@
require "./test.pl";
-plan(tests => 1);
+plan(tests => 2);
my $r;
my @tmpfiles = ();
@@ -36,5 +36,11 @@
progfile => $filename,
);
like($r, qr/^main,swdtest.tmp,9;Foo,swdtest.tmp,5;Foo,swdtest.tmp
+...
+
+ $r = runperl(
+ switches => [ '-Ilib', '-d:switchd=1,2' ],
+ progfile => $filename,
+ );
+ like($r, qr/^main,swdtest.tmp,9;Foo,swdtest.tmp,5;Foo,swdtest.t..
+.
perl-5.8.8]$ perl ./t/run/new_switchd.t
1..2
ok 1
syntax error at swdtest.tmp line 2, near "sub bar "
(Might be a runaway multi-line ;; string starting on line 0)
Execution of swdtest.tmp aborted due to compilation errors.
not ok 2
# Failed at ./t/run/new_switchd.t line 44
# got ''
# expected /(?i-xsm:^main,swdtest.tmp,9;Foo,swdtest...
I think the syntax either never worked, or stopped working with
the sprintf patching and no one noticed. Shame, I was going to use it...