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

Refcount problem #1072

Closed
p5pRT opened this issue Jan 24, 2000 · 8 comments
Closed

Refcount problem #1072

p5pRT opened this issue Jan 24, 2000 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 24, 2000

Migrated from rt.perl.org#2025 (status was 'resolved')

Searchable as RT2025$

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2000

From eivind@dev1.hs.yes.no

The following snippet of perl shows what I believe to be a refcount problem.
With the reference in place, it seems that the file should not be closed,
yet it is. #perl on efnet seemed to agree that this was a bug.

#!/usr/bin/perl -w

use strict;
my $retval;

#
# Change 0/1 to show code that should be equal give different results
#
if (1) {
  {
  local *FILE;
  open(FILE, ">/dev/stdout")
  or die "Unable to open output file\n";
  $retval = \*FILE;
  }
  print $retval "Output that fails\n";
} else {
  {
  local *FILE;
  open(FILE, ">/dev/stdout")
  or die "Unable to open output file\n";
  $retval = \*FILE;
  print $retval "Output that works\n";
  }
}

Perl Info


Site configuration information for perl 5.00503:

Configured by markm at $Date: 1999/05/05 19:42:40 $.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
  Platform:
    osname=freebsd, osvers=4.0-current, archname=i386-freebsd
    uname='freebsd freefall.freebsd.org 4.0-current freebsd 4.0-current #0: $Date: 1999/05/05 19:42:40 $'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='undef', gccversion=egcs-2.91.66 19990314 (egcs-1.1.2 release)
    cppflags=''
    ccflags =''
    stdchar='char', d_stdstdio=undef, usevfork=true
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-Wl,-E'
    libpth=/usr/lib
    libs=-lm -lc -lcrypt
    libc=/usr/lib/libc.so, so=so, useshrplib=true, libperl=libperl.so.3
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-DPIC -fpic', lddlflags='-shared'

Locally applied patches:
    


@INC for perl 5.00503:
    /usr/libdata/perl/5.00503/mach
    /usr/libdata/perl/5.00503
    /usr/local/lib/perl5/site_perl/5.005/i386-freebsd
    /usr/local/lib/perl5/site_perl/5.005
    .


Environment for perl 5.00503:
    HOME=/root
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH=:/usr/local/lib:/usr/local/lib:/usr/local/lib:/usr/local/lib
    LOGDIR (unset)
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:/root/bin:/usr/local/jdk/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2000

From @gsar

On Mon, 24 Jan 2000 14​:49​:39 +0100, EE wrote​:

#
# Change 0/1 to show code that should be equal give different results
#
if (1) {
{
local *FILE;
open(FILE, ">/dev/stdout")
or die "Unable to open output file\n";
$retval = \*FILE;
}
print $retval "Output that fails\n";
} else {
{
local *FILE;
open(FILE, ">/dev/stdout")
or die "Unable to open output file\n";
$retval = \*FILE;
print $retval "Output that works\n";
}
}

local(*FOO) has always localized the contents of *FOO (the GvGP in
gutspeech). In fact, this is the behavior that makes local(*FOO)
also localize $FOO, %FOO, @​FOO and the filehandle FOO.

Thus the above is akin to​:

  if (1) {
  {
  local $FILE{GP};
  open($FILE{GP}, ">/dev/stdout")
  or die "Unable to open output file\n";
  $retval = \%FILE;
  }
  print { $FILE{GP} } "Output that fails\n";
  } else {
  {
  local $FILE{GP};
  open($FILE{GP}, ">/dev/stdout")
  or die "Unable to open output file\n";
  $retval = \%FILE;
  print { $FILE{GP} } "Output that works\n";
  }
  }

So I don't think this can be easily fixed without breaking other
things.

Sarathy
gsar@​ActiveState.com

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2000

From @gsar

On Tue, 25 Jan 2000 13​:40​:16 PST, I wrote​:

   $retval = \\%FILE;

}
print { $FILE{GP} } "Output that fails\n";
[...]
$retval = \%FILE;
print { $FILE{GP} } "Output that works\n";
}

Oops, I meant to say "print { $retval->{GP} }" in both places.

Sarathy
gsar@​ActiveState.com

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2000

From [Unknown Contact. See original ticket]

local(*FOO) has always localized the contents of *FOO (the GvGP in
gutspeech). In fact, this is the behavior that makes local(*FOO)
also localize $FOO, %FOO, @​FOO and the filehandle FOO.

I believe that the standard way to deal with this has been to use
*FH not \*FH. Notice how the examples in perldata on returning
local handles do not use backslash.

--tom

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2000

From @gsar

On Tue, 25 Jan 2000 14​:56​:12 MST, Tom Christiansen wrote​:

local(*FOO) has always localized the contents of *FOO (the GvGP in
gutspeech). In fact, this is the behavior that makes local(*FOO)
also localize $FOO, %FOO, @​FOO and the filehandle FOO.

I believe that the standard way to deal with this has been to use
*FH not \*FH. Notice how the examples in perldata on returning
local handles do not use backslash.

Yes, *FH is already a kind of a reference [*], so returning \*FH is like
returning a reference to a reference.

[*] Except that it refers to more than one kind of thingy at the same
time.

Sarathy
gsar@​ActiveState.com

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2000

From [Unknown Contact. See original ticket]

On Tue, Jan 25, 2000 at 02​:56​:12PM -0700, Tom Christiansen wrote​:

local(*FOO) has always localized the contents of *FOO (the GvGP in
gutspeech). In fact, this is the behavior that makes local(*FOO)
also localize $FOO, %FOO, @​FOO and the filehandle FOO.

I believe that the standard way to deal with this has been to use
*FH not \*FH.

I don't know where I picked up the habit of using \*FH (I distinctly
remember reading it *somewhere* in the docs, but I've been unable to
find where that was.) The problem is that the reference from \*FH
works at all. If printing to \*FH hadn't worked, then the rest of the
problem would never appear - but as it is, this can cause subtle bugs.

When I discovered this, I thought I was returning a locked filehandle,
which was supposed to expire when the variable it was assigned to in
the calling function went out of scope (with a "honourary close()" in
order to make sure optimization didn't get rid of it early -
unchecked, as nothing could be done if it failed.) This was supposed
to act as a mutex to serialize multiple copies of the program in
question, but actually no longer did.

Notice how the examples in perldata on returning local handles do
not use backslash.

This is the solution I used to work around the problem once I
identified exactly where the problem came from.

Eivind.

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2000

From [Unknown Contact. See original ticket]

I don't know where I picked up the habit of using \*FH (I distinctly
remember reading it *somewhere* in the docs, but I've been unable to
find where that was.)

It's because at one point, use strict require \*FH not *FH, so people
started using the former. In fact, at once point, returning the local \*FH
worked, too. But then that got changed, and use strict was fixed. I don't
know any reason beyond blessing to use \*FH.

--tom

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen writes​:

I don't know where I picked up the habit of using \*FH (I distinctly
remember reading it *somewhere* in the docs, but I've been unable to
find where that was.)

It's because at one point, use strict require \*FH not *FH, so people
started using the former. In fact, at once point, returning the local \*FH
worked, too. But then that got changed, and use strict was fixed. I don't
know any reason beyond blessing to use \*FH.

At some point of Perl history returning globs from subroutines was
just asking for trouble. Almost nothing worked.

I think I have some mindblocks left from this time. I still cannot
make myself return *GLOB if returning \*GLOB works (as it should). It
does no help that \*GLOB is a scalar, not some obscure aggregate of
heavy magical things...

Ilya

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

No branches or pull requests

1 participant