Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reset() silently fails to reset some variables like $1, $^W #20763

Closed
mauke opened this issue Feb 3, 2023 · 3 comments · Fixed by #21030
Closed

reset() silently fails to reset some variables like $1, $^W #20763

mauke opened this issue Feb 3, 2023 · 3 comments · Fixed by #21030

Comments

@mauke
Copy link
Contributor

mauke commented Feb 3, 2023

Description
reset() works with some core variables (e.g. $0, $^X), but not others (e.g. $|, $1, $^W).

Steps to Reproduce

$ perl -wE '$| = 1; reset "|"; say $|'
1
$ perl -wE '"hello" =~ /(.*)/; reset "0-9"; say $0, $1'
Use of uninitialized value $0 in say at -e line 1.
hello
$ perl -wE 'reset "\x01-\x1f"; say $^X, $^W'
Use of uninitialized value $^X in say at -e line 1.
1

Expected behavior
I would've expected all of these variables to be reset to undef, or if that's not possible (eyeing $| in particular), an error or warning to be generated.

Perl configuration

Summary of my perl5 (revision 5 version 36 subversion 0) configuration:
   
  Platform:
    osname=linux
    osvers=5.15.0-53-generic
    archname=x86_64-linux
    uname='linux luum 5.15.0-53-generic #59-ubuntu smp mon oct 17 18:53:30 utc 2022 x86_64 x86_64 x86_64 gnulinux '
    config_args='-de -Dprefix=/home/mauke/perl5/perlbrew/perls/perl-5.36.0 -Duseshrplib -Aeval:scriptdir=/home/mauke/perl5/perlbrew/perls/perl-5.36.0/bin'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=undef
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='cc'
    ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='-O2'
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='11.3.0'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='cc'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib /usr/lib64
    libs=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/x86_64-linux-gnu/libc.so.6
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.35'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/home/mauke/perl5/perlbrew/perls/perl-5.36.0/lib/5.36.0/x86_64-linux/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_TIMES
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
  Built under linux
  Compiled at Nov 21 2022 09:12:40
  %ENV:
    PERLBREW_BASHRC_VERSION="0.74"
    PERLBREW_HOME="/home/mauke/.perlbrew"
    PERLBREW_MANPATH="/home/mauke/perl5/perlbrew/perls/perl-5.36.0/man"
    PERLBREW_PATH="/home/mauke/perl5/perlbrew/bin:/home/mauke/perl5/perlbrew/perls/perl-5.36.0/bin"
    PERLBREW_PERL="perl-5.36.0"
    PERLBREW_ROOT="/home/mauke/perl5/perlbrew"
    PERLBREW_VERSION="0.94"
    PERLDOC="-oterm"
  @INC:
    /home/mauke/perl5/perlbrew/perls/perl-5.36.0/lib/site_perl/5.36.0/x86_64-linux
    /home/mauke/perl5/perlbrew/perls/perl-5.36.0/lib/site_perl/5.36.0
    /home/mauke/perl5/perlbrew/perls/perl-5.36.0/lib/5.36.0/x86_64-linux
    /home/mauke/perl5/perlbrew/perls/perl-5.36.0/lib/5.36.0
@Leont
Copy link
Contributor

Leont commented Feb 3, 2023

Yeah, those are variables that are lazily initialized (in gv_magicalize), so they will get reinitialized after reset.

@demerphq
Copy link
Collaborator

demerphq commented Feb 4, 2023

I wouldn't expect reset to change $1 and other regex vars, they aren't writable, so arguably there is nothing to reset. We don't have a variable that represent PL_curpm currently, and the regexp vars are essentially ties that expose the state of PL_curpm.

@tonycoz
Copy link
Contributor

tonycoz commented Feb 14, 2023

The problem with $1 and $^W isn't that they're gv_magicalized after the reset, but that set magic isn't called.

gv_magicalize() is called for each of the names during compilation before the reset is called, e.g, from debugging the $^W test case:

Breakpoint 2, S_gv_magicalize (gv=0x555555c14690, stash=0x555555bf0648, 
    name=0x555555c1b281 "\027", len=1, sv_type=SVt_PV) at gv.c:2068
2068    {
(gdb) bt
#0  S_gv_magicalize (gv=0x555555c14690, stash=0x555555bf0648, 
    name=0x555555c1b281 "\027", len=1, sv_type=SVt_PV) at gv.c:2068
#1  0x0000555555610c0e in Perl_gv_fetchpvn_flags (
    nambeg=0x555555c1b281 "\027", full_len=1, flags=1, sv_type=SVt_PV)
    at gv.c:2693
#2  0x0000555555656f8c in S_pending_ident () at toke.c:9973
#3  0x000055555565511d in Perl_yylex () at toke.c:9592
...
(gdb) c
Continuing.

Breakpoint 1, Perl_sv_resetpvn (s=0x555555c1d0b0 "\001-\037", len=3, 
    stash=0x555555bf0648) at sv.c:10065
10065   {
(gdb) c

If I modify sv_resetpvn() to call set magic, we get more reasonable (if noisy) results:

tony@venus:.../git/perl6$ ./perl -Ilib -wE 'reset "0-9"; say $0, $1'
Modification of a read-only value attempted at -e line 1.
tony@venus:.../git/perl6$ ./perl -Ilib -wE 'reset "\x01-\x1f"; say $^X, $^W'
Use of uninitialized value in symbol reset at -e line 1.
Use of uninitialized value in symbol reset at -e line 1.
0

Note that $1 etc aren't marked read only, the error there is thrown by the magic handling. If $1 was marked read only sv_resetpvn() would skip trying to modify it.

Similarly with the uninitialized value warnings: one for $^H and another for $^W since it was "summoned" during compilation.

tonycoz added a commit to tonycoz/perl5 that referenced this issue Apr 13, 2023
tonycoz added a commit to tonycoz/perl5 that referenced this issue Apr 17, 2023
reset() with an argument would clear the specified SVs when requested
but didn't call set magic, this would result in the effect on magic
variables not applying, such as the $| and $^W used in the ticket.

This isn't a problem for AVs and HVs as their corresponding clear
functions do call the appropriate clear magic.

Fixes Perl#20763
tonycoz added a commit that referenced this issue Jul 4, 2023
reset() with an argument would clear the specified SVs when requested
but didn't call set magic, this would result in the effect on magic
variables not applying, such as the $| and $^W used in the ticket.

This isn't a problem for AVs and HVs as their corresponding clear
functions do call the appropriate clear magic.

Fixes #20763
khwilliamson pushed a commit to khwilliamson/perl5 that referenced this issue Jul 10, 2023
reset() with an argument would clear the specified SVs when requested
but didn't call set magic, this would result in the effect on magic
variables not applying, such as the $| and $^W used in the ticket.

This isn't a problem for AVs and HVs as their corresponding clear
functions do call the appropriate clear magic.

Fixes Perl#20763
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants