Closed p5pRT closed 21 years ago
plover% perl5.7.3 -MB -e 'print B::SV::FLAGS(\"fooey")' Segmentation fault (core dumped)
I don't know if this persists in 5.8.
On Wed\, Aug 21\, 2002 at 01:50:36AM -0000\, Mark-Jason Dominus wrote:
plover% perl5\.7\.3 \-MB \-e 'print B​::SV​::FLAGS\(\\"fooey"\)' Segmentation fault \(core dumped\)
I don't know if this persists in 5.8.
5.8.0\, 5.6.1\, 5.6.0 and 5.5.3. Looks like it goes right back to the beginning.
--
Michael G. Schwern \schwern@​pobox\.com http://www.pobox.com/~schwern/ Perl Quality Assurance \perl\-qa@​perl\.org Kwalitee Is Job One I do have a cause though. It is obscenity. I'm for it. -- Tom Lehrer "Smut"
Mark-Jason Dominus wrote (via RT):
plover% perl5\.7\.3 \-MB \-e 'print B​::SV​::FLAGS\(\\"fooey"\)' Segmentation fault \(core dumped\)
\"fooey" isn't a B::SV object\, so this is a pretty reasonable reaction (though a better error message would be nice).
I expect you meant:
perl -MB=svref_2object -e 'print svref_2object(\"fooey")->FLAGS'
.robin.
On Wed\, 21 Aug 2002 11:42:25 +0100\, robin@kitsite.com wrote:
Mark-Jason Dominus wrote (via RT):
plover% perl5\.7\.3 \-MB \-e 'print B​::SV​::FLAGS\(\\"fooey"\)' Segmentation fault \(core dumped\)
\"fooey" isn't a B::SV object\, so this is a pretty reasonable reaction (though a better error message would be nice).
I expect you meant:
perl -MB=svref_2object -e 'print svref_2object(\"fooey")->FLAGS'
Actually\, print B::SV::FLAGS(\\"fooey") works\, because a B::foo object is just a ref to an IV containing the pointer\, and \"fooey" in numeric is the desired pointer:
~/pbed $perl -MB -le'print B::PV::PV(\\"fooey")' fooey
The following patch would take away that loophole and prevent the coredump. Untested except in this particular case:
~/bleadperl/perl $./perl -Ilib -MB -e'B::SV::FLAGS(\"fooey")' sv is not a B::SV object at -e line 1.
Suggestions for a better-worded error message appreciated. I'm not sure $var should be in the message at all.
On Fri\, 23 Aug 2002 11:50:41 +0100\, robin@kitsite.com wrote:
On Thu\, Aug 22\, 2002 at 04:30:53PM -0700\, Yitzchak Scott-Thoennes wrote:
Actually\, print B::SV::FLAGS(\\"fooey") works\, because a B::foo object is just a ref to an IV containing the pointer\, and \"fooey" in numeric is the desired pointer:
Cute!
The patch seems sensible too.
It will slow things down\, perhaps even dramatically. It may not be worth it just to make sure methods are called as such and not as regular subs. (Though in most other modules\, methods called erroneously as non-methods don't coredump\, so perhaps it behooves us to take extra care.)
I'm having some computer trouble at the moment. Is anyone interested in timing a run of B::Deparse and B::Concise on a large body of code (perhaps the perl test suite?) with and without the patch? (As well as a make test with the patch\, which I haven't been able to do.)
For convenience\, the patch is attached below (same as previously posted).
Yitzchak Scott-Thoennes wrote:
It will slow things down\, perhaps even dramatically. It may not be worth it just to make sure methods are called as such and not as regular subs. (Though in most other modules\, methods called erroneously as non-methods don't coredump\, so perhaps it behooves us to take extra care.)
I'm having some computer trouble at the moment. Is anyone interested in timing a run of B::Deparse and B::Concise on a large body of code (perhaps the perl test suite?) with and without the patch? (As well as a make test with the patch\, which I haven't been able to do.)
I ran 'make test.deparse' with and without the patch :
without :
Failed 54 test scripts out of 657\, 91.78% okay. u=3.48 s=0.56 cu=502.37 cs=36.99 scripts=657 tests=67891
with :
Failed 54 test scripts out of 657\, 91.78% okay. u=3.23 s=0.54 cu=544.4 cs=35.82 scripts=657 tests=67891
sthoenna@efn.org (Yitzchak Scott-Thoennes) wrote: :On Fri\, 23 Aug 2002 11:50:41 +0100\, robin@kitsite.com wrote: :>On Thu\, Aug 22\, 2002 at 04:30:53PM -0700\, Yitzchak Scott-Thoennes wrote: :>> Actually\, print B::SV::FLAGS(\\"fooey") works\, because a B::foo object :>> is just a ref to an IV containing the pointer\, and \"fooey" in numeric :>> is the desired pointer: :> :>Cute! :> :>The patch seems sensible too. : :It will slow things down\, perhaps even dramatically. It may not be :worth it just to make sure methods are called as such and not as :regular subs. (Though in most other modules\, methods called :erroneously as non-methods don't coredump\, so perhaps it behooves us :to take extra care.)
Thanks for the patch\, but I think it is not addressing the correct issue; more important to solve first should be the documentational inadequacies that led mjd to attempt this: perl -MB -e 'print B::SV::FLAGS(\"fooey")' in the first place.
Hugo
On Sun\, 25 Aug 2002 16:28:46 +0100\, hv@crypt.org wrote:
sthoenna@efn.org (Yitzchak Scott-Thoennes) wrote: :It will slow things down\, perhaps even dramatically. It may not be :worth it just to make sure methods are called as such and not as :regular subs. (Though in most other modules\, methods called :erroneously as non-methods don't coredump\, so perhaps it behooves us :to take extra care.)
Thanks for the patch\, but I think it is not addressing the correct issue; more important to solve first should be the documentational inadequacies that led mjd to attempt this: perl -MB -e 'print B::SV::FLAGS(\"fooey")' in the first place.
How's this? Mangled the overview paragraph and moved B::MAGIC info out from the B::SV subclasses. Mark-Jason\, would you have found this helpful?
sthoenna@efn.org (Yitzchak Scott-Thoennes) wrote:
On Sun\, 25 Aug 2002 16:28:46 +0100\, hv@crypt.org wrote:
Thanks for the patch\, but I think it is not addressing the correct issue; more important to solve first should be the documentational inadequacies that led mjd to attempt this: perl -MB -e 'print B::SV::FLAGS(\"fooey")' in the first place.
How's this? Mangled the overview paragraph and moved B::MAGIC info out from the B::SV subclasses. Mark-Jason\, would you have found this helpful?
Sorry to be negative\, but no\, not in the slightest. In fact\, I'm so clueless that I can't even understand how those changes are supposed to help.
I have no objection to your changes\, but here's what I would suggest that I think would have helped me. The major changes are to add an 'overview' section and to move the explanation of the utility functions up before the explanations of the methods. That way\, the front part of the manual discusses the functions one must call first.
In particular\, the very important function 'svref_2object'\, which I missed completely\, it now closer to the top of the document\, instead of being buried 80% of the way through.
I also made some minor formatting changes\, and added pictures of the inheritance hierarchies.
I hope this is helpful.
--- ext/B/B.pm 2002/08/26 01:29:27 1.1 +++ ext/B/B.pm 2002/08/26 02:28:28 @@ -324\,6 +324\,182 @@ things as SVs\, OPs and the internal symbol table and syntax tree of a program.
+=head1 OVERVIEW
+
+The C\ module contains a set of utility functions for querying the
+current state of the Perl interpreter; typically these functions
+return objects from the B::SV and B::OP classes\, or their derived
+classes. These classes in turn define methods for querying the
+resulting objects about their own internal state.
+
+=head1 Utility Functions
+
+The C\ module exports a variety of functions: some are simple
+utility functions\, others provide a Perl program with a way to
+get an initial "handle" on an internal object.
+
+=head2 Functions Returning C\<B::SV>\, C\<B::AV>\, C\<B::HV>\, and C\<B::CV> objects
+
+For descriptions of the class hierachy of these objects and the
+methods that can be called on them\, see below\, L\<"OVERVIEW OF
+CLASSES"> and L\<"SV-RELATED CLASSES">.
+
+=item sv_undef
+
+Returns the SV object corresponding to the C variable C\<sv_undef>.
+
+=item sv_yes
+
+Returns the SV object corresponding to the C variable C\<sv_yes>.
+
+=item sv_no
+
+Returns the SV object corresponding to the C variable C\<sv_no>.
+
+=item svref_2object(SVREF)
+
+Takes a reference to any Perl value\, and turns the referred-to value
+into an object in the appropriate B::OP-derived or B::SV-derived
+class. Apart from functions such as C\<main_root>\, this is the primary
+way to get an initial "handle" on an internal perl data structure
+which can then be followed with the other access methods.
+
+=item amagic_generation
+
+Returns the SV object corresponding to the C variable C\<amagic_generation>.
+
+=item C\<init_av>
+
+Returns the AV object (i.e. in class B::AV) representing INIT blocks.
+
+=item begin_av
+
+Returns the AV object (i.e. in class B::AV) representing BEGIN blocks.
+
+=item end_av
+
+Returns the AV object (i.e. in class B::AV) representing END blocks.
+
+=item comppadlist
+
+Returns the AV object (i.e. in class B::AV) of the global comppadlist.
+
+=item regex_padav
+
+Only when perl was compiled with ithreads.
+
+=item C\<main_cv>
+
+Return the (faked) CV corresponding to the main part of the Perl
+program.
+
+=back
+
+=head2 Functions for Examining the Symbol Table
+
+=over 4
+
+=item walksymtable(SYMREF\, METHOD\, RECURSE\, PREFIX)
+
+Walk the symbol table starting at SYMREF and call METHOD on each
+symbol (a B::GV object) visited. When the walk reaches package
+symbols (such as "Foo::") it invokes RECURSE\, passing in the symbol
+name\, and only recurses into the package if that sub returns true.
+
+PREFIX is the name of the SYMREF you're walking.
+
+For example:
+
+ # Walk CGI's symbol table calling print_subs on each symbol.
+ # Recurse only into CGI::Util::
+ walksymtable(\%CGI::\, 'print_subs'\, sub { $_[0] eq 'CGI::Util::' }\,
+ 'CGI::');
+
+print_subs() is a B::GV method you have declared. Also see L\<"B::GV
+Methods">\, below.
+
+=back
+
+=head2 Functions Returning C\<B::OP> objects or for walking op trees
+
+For descriptions of the class hierachy of these objects and the
+methods that can be called on them\, see below\, L\<"OVERVIEW OF
+CLASSES"> and L\<"OP-RELATED CLASSES">.
+
+=over 4
+
+=item main_root
+
+Returns the root op (i.e. an object in the appropriate B::OP-derived
+class) of the main part of the Perl program.
+
+=item main_start
+
+Returns the starting op of the main part of the Perl program.
+
+=item walkoptree(OP\, METHOD)
+
+Does a tree-walk of the syntax tree based at OP and calls METHOD on
+each op it visits. Each node is visited before its children. If
+C\<walkoptree_debug> (see below) has been called to turn debugging on then
+the method C\<walkoptree_debug> is called on each op before METHOD is
+called.
+
+=item walkoptree_debug(DEBUG)
+
+Returns the current debugging flag for C\
The C structures used by Perl's internals to hold SV and OP @@ -331\,9 +507\,12 @@ class hierarchy and the C\ module gives access to them via a true object hierarchy. Structure fields which point to other objects (whether types of SV or types of OP) are represented by the C\ -module as Perl objects of the appropriate class. The bulk of the C\ -module is the methods for accessing fields of these structures. Note -that all access is read-only: you cannot modify the internals by +module as Perl objects of the appropriate class. + +The bulk of the C\ module is the methods for accessing fields of +these structures. + +Note that all access is read-only. You cannot modify the internals by using this module.
=head2 SV-RELATED CLASSES
@@ -341\,15 +520\,35 @@
B::IV\, B::NV\, B::RV\, B::PV\, B::PVIV\, B::PVNV\, B::PVMG\, B::BM\, B::PVLV\,
B::AV\, B::HV\, B::CV\, B::GV\, B::FM\, B::IO. These classes correspond in
the obvious way to the underlying C structures of similar names. The
-inheritance hierarchy mimics the underlying C "inheritance". Access
-methods correspond to the underlying C macros for field access\,
+inheritance hierarchy mimics the underlying C "inheritance":
+
+ B::SV
+ +--------------------------------+----------------------+
+ | | |
+ B::PV B::IV B::RV
+ | \ \,-----------'`.
+ | \ \,----------' `.
+ | B::PVIV B::NV
+ `. \,---------'`.
+ `---------. \,--------' `.
+ B::PVNV B::PVMG
+ |
+ +------+-----+----+------+-----+-----+
+ | | | | | | |
+ B::PVLV B::BM B::AV B::GV B::HV B::CV B::IO
+ |
+ |
+ B::FM
+
+
+Access methods correspond to the underlying C macros for field access\,
usually with the leading "class indication" prefix removed (Sv\, Av\,
Hv\, ...). The leading prefix is only left in cases where its removal
would cause a clash in method name. For example\, C\
-=head2 B::SV METHODS +=head2 B::SV Methods
=over 4
@@ -359\,7 +558\,7 @@
=back
-=head2 B::IV METHODS +=head2 B::IV Methods
=over 4
@@ -387\,7 +586\,7 @@
=back
-=head2 B::NV METHODS +=head2 B::NV Methods
=over 4
@@ -397\,7 +596\,7 @@
=back
-=head2 B::RV METHODS +=head2 B::RV Methods
=over 4
@@ -405\,7 +604\,7 @@
=back
-=head2 B::PV METHODS +=head2 B::PV Methods
=over 4
@@ -434\,7 +633\,7 @@
=back
-=head2 B::PVMG METHODS +=head2 B::PVMG Methods
=over 4
@@ -444\,7 +643\,7 @@
=back
-=head2 B::MAGIC METHODS +=head2 B::MAGIC Methods
=over 4
@@ -473\,7 +672\,7 @@
=back
-=head2 B::PVLV METHODS +=head2 B::PVLV Methods
=over 4
@@ -487\,7 +686\,7 @@
=back
-=head2 B::BM METHODS +=head2 B::BM Methods
=over 4
@@ -501\,7 +700\,7 @@
=back
-=head2 B::GV METHODS +=head2 B::GV Methods
=over 4
@@ -556\,7 +755\,7 @@
=back
-=head2 B::IO METHODS +=head2 B::IO Methods
=over 4
@@ -595\,7 +794\,7 @@
=back
-=head2 B::AV METHODS +=head2 B::AV Methods
=over 4
@@ -611\,7 +810\,7 @@
=back
-=head2 B::CV METHODS +=head2 B::CV Methods
=over 4
@@ -643\,7 +842\,7 @@
=back
-=head2 B::HV METHODS +=head2 B::HV Methods
=over 4
@@ -665\,15 +864\,32 @@
=head2 OP-RELATED CLASSES
-B::OP\, B::UNOP\, B::BINOP\, B::LOGOP\, B::LISTOP\, B::PMOP\, -B::SVOP\, B::PADOP\, B::PVOP\, B::CVOP\, B::LOOP\, B::COP. -These classes correspond in -the obvious way to the underlying C structures of similar names. The -inheritance hierarchy mimics the underlying C "inheritance". Access -methods correspond to the underlying C structre field names\, with the -leading "class indication" prefix removed (op_). +C\<B::OP>\, C\<B::UNOP>\, C\<B::BINOP>\, C\<B::LOGOP>\, C\<B::LISTOP>\, C\<B::PMOP>\, +C\<B::SVOP>\, C\<B::PADOP>\, C\<B::PVOP>\, C\<B::CVOP>\, C\<B::LOOP>\, C\<B::COP>. + +These classes correspond in the obvious way to the underlying C +structures of similar names. The inheritance hierarchy mimics the +underlying C "inheritance": + + B::OP + | + +---------------+--------+--------+------+ + | | | | | + B::UNOP B::SVOP B::PADOP B::CVOP B::COP + \,' `-. + / `--. + B::BINOP B::LOGOP + | + | + B::LISTOP + \,' `. + / \ + B::LOOP B::PMOP + +Access methods correspond to the underlying C structre field names\, +with the leading "class indication" prefix (C\<"op_">) removed.
-=head2 B::OP METHODS +=head2 B::OP Methods
=over 4
@@ -739\,7 +955\,7 @@
=back
-=head2 B::PMOP METHODS +=head2 B::PMOP Methods
=over 4
@@ -791\,7 +1007\,7 @@
=back
-=head2 B::LOOP METHODS +=head2 B::LOOP Methods
=over 4
@@ -803\,7 +1019\,7 @@
=back
-=head2 B::COP METHODS +=head2 B::COP Methods
=over 4
@@ -821\,148 +1037\,6 @@
=back
-=head1 FUNCTIONS EXPORTED BY C\
-
-The C\ module exports a variety of functions: some are simple
-utility functions\, others provide a Perl program with a way to
-get an initial "handle" on an internal object.
-
-=over 4
-
-=item main_cv
-
-Return the (faked) CV corresponding to the main part of the Perl
-program.
-
-=item init_av
-
-Returns the AV object (i.e. in class B::AV) representing INIT blocks.
-
-=item begin_av
-
-Returns the AV object (i.e. in class B::AV) representing BEGIN blocks.
-
-=item end_av
-
-Returns the AV object (i.e. in class B::AV) representing END blocks.
-
-=item main_root
-
-Returns the root op (i.e. an object in the appropriate B::OP-derived
-class) of the main part of the Perl program.
-
-=item main_start
-
-Returns the starting op of the main part of the Perl program.
-
-=item comppadlist
-
-Returns the AV object (i.e. in class B::AV) of the global comppadlist.
-
-=item regex_padav
-
-Only when perl was compiled with ithreads.
-
-=item sv_undef
-
-Returns the SV object corresponding to the C variable C\<sv_undef>.
-
-=item sv_yes
-
-Returns the SV object corresponding to the C variable C\<sv_yes>.
-
-=item sv_no
-
-Returns the SV object corresponding to the C variable C\<sv_no>.
-
-=item amagic_generation
-
-Returns the SV object corresponding to the C variable C\<amagic_generation>.
-
-=item walkoptree(OP\, METHOD)
-
-Does a tree-walk of the syntax tree based at OP and calls METHOD on
-each op it visits. Each node is visited before its children. If
-C\<walkoptree_debug> (q.v.) has been called to turn debugging on then
-the method C\<walkoptree_debug> is called on each op before METHOD is
-called.
-
-=item walkoptree_debug(DEBUG)
-
-Returns the current debugging flag for C\
=head1 AUTHOR
I said:
sthoenna@efn.org (Yitzchak Scott-Thoennes) wrote:
How's this? Mangled the overview paragraph and moved B::MAGIC info out from the B::SV subclasses. Mark-Jason\, would you have found this helpful?
Sorry to be negative\, but no\, not in the slightest.
It occurs to me\, on further reflection\, that the real problem here is not so much with the documentation as with the interface. There is this big fancy OO hierarchy\, but none of the classes has a constructor method!
It seems to me that it would be very easy to add such. Just adding
B::SV::new {
my $expected_class = shift();
my $self = B::svref_2object(shift());
my $actual_class = ref $self;
croak "..." unless $actual_class->isa($expected_class);
return $self;
}
should suffice; the other classes would then inherit B::SV::new. Now the user can ask for
B::SV->new(\"fooey")->FLAGS
which is very ordinary-looking.
If nobody sees a problem with this\, I could produce a patch including docs\, but not today. I am copying Malcolm because he is more likely to see a problem than anyone else.
I am copying Malcolm because he is more likely to see a problem than anyone else.
I was mistaken. Malcolm's address has gone bad.
On Sun\, 25 Aug 2002 22:31:54 -0400\, mjd@plover.com wrote:
I have no objection to your changes\, but here's what I would suggest that I think would have helped me. The major changes are to add an 'overview' section and to move the explanation of the utility functions up before the explanations of the methods. That way\, the front part of the manual discusses the functions one must call first.
In particular\, the very important function 'svref_2object'\, which I missed completely\, it now closer to the top of the document\, instead of being buried 80% of the way through.
I also made some minor formatting changes\, and added pictures of the inheritance hierarchies.
I hope this is helpful.
Excellent! Thanks.
--- ext/B/B.pm 2002/08/26 01:29:27 1.1 +++ ext/B/B.pm 2002/08/26 02:28:28 +=head2 Functions Returning C\<B::SV>\, C\<B::AV>\, C\<B::HV>\, and C\<B::CV> objects
Why not 'B::SV or a subclass'? Why list particular subclasses but not all of them?
+=head2 Functions Returning C\<B::SV>\, C\<B::AV>\, C\<B::HV>\, and C\<B::CV> objects
Why not 'B::SV or a subclass'? Why list particular subclasses but not all of them?
Because those are the most interesting ones.
It's obvious that 'SV' include 'PVNV' as a special case. It's less obvious that it includes 'AV'.
Suppose someone is looking for B::begin_av\, which they know will return an AV. If they see
B::SV or a subclass
they might think 'oh\, that's for functions that return scalars' and go onward looking for the section about arrays.
If you list all of them\, the list becomes unreadable and nothing is gained.
Since I have you around\, do you know why there is:
=item C\<init_av>
Returns the AV object (i.e. in class B::AV) representing INIT blocks.
=item begin_av
Returns the AV object (i.e. in class B::AV) representing BEGIN blocks.
=item end_av
Returns the AV object (i.e. in class B::AV) representing END blocks.
But no check_av?
On Mon\, 26 Aug 2002\, Mark-Jason Dominus wrote:
=item C\<init\_av> =item begin\_av =item end\_av
Why is only one of those C\<>?
R.
On Mon\, 26 Aug 2002 16:21:41 -0400\, mjd@plover.com wrote:
Since I have you around\, do you know why there is: =item C\<init_av> =item begin_av =item end_av But no check_av?
Perhaps no one needed it yet?
BTW\, I see this is wrong:
+ | B::PVIV B::NV + `. \,---------'`. + `---------. \,--------' `. + B::PVNV B::PVMG
PVNV is the base for PVMG\, not plain NV.
Unrelated to your reorganization\, there are a few things I see right off missing from the doc: B::OBJECT (what is it for\, anyway?)\, B::SPECIAL\, B::NULL\, and the as_string method that's provided for B::([IP]V|NULL).
Unrelated to your reorganization\, there are a few things I see right off missing from the doc: B::OBJECT (what is it for\, anyway?)\,
I don't think it has any methods. I supposed that it was there in case any methods came along that needed to be shared by B::SV and B::OP\, so there would be a place to put them if so.
Quoting Mark-Jason Dominus \mjd@​plover\.com:
Since I have you around\, do you know why there is:
=item C\<init\_av> Returns the AV object \(i\.e\. in class B​::AV\) representing INIT
blocks.
=item begin\_av Returns the AV object \(i\.e\. in class B​::AV\) representing BEGIN
blocks.
=item end\_av Returns the AV object \(i\.e\. in class B​::AV\) representing END
blocks.
But no check_av?
Because it doesn't work :
typically B:: backends are executed at CHECK-time. The CHECK block that executes the B:: backend is executed after the CHECK blocks that appear in the analyzed script (CHECK blocks are executed in reverse...) and thus those CHECK blocks have been removed from PL_checkav.
A simple fix is to make CHECK blocks execute in the same order that they appear in the scripts (like INIT and BEGIN blocks.)
Is there a good reason why CHECK blocks are executed in reverse ?
Quoting Rafael Garcia-Suarez \rgarciasuarez@​free\.fr:
But no check_av?
Because it doesn't work :
typically B:: backends are executed at CHECK-time. The CHECK block that executes the B:: backend is executed after the CHECK blocks that appear in the analyzed script (CHECK blocks are executed in reverse...) and thus those CHECK blocks have been removed from PL_checkav.
A simple fix is to make CHECK blocks execute in the same order that they appear in the scripts (like INIT and BEGIN blocks.)
Is there a good reason why CHECK blocks are executed in reverse ?
Anyway\, it's documented that way (in perlmod :)
Similar to C\
So\, to have a working B::check_av\, one need a similar hack than for BEGIN blocks : save them in a separate array after execution (when the global boolean PL_savebegin is true.)
Mark-Jason Dominus \mjd@​plover\.com wrote: :I have no objection to your changes\, but here's what I would suggest :that I think would have helped me.
Thanks\, applied as #17797.
:I also made some minor formatting changes\, and added pictures of the :inheritance hierarchies.
I adjusted the SV::* inheritance picture for Yitzhak's comment :PVNV is the base for PVMG\, not plain NV. ..... please check that it is correct.
Hugo
I adjusted the SV::* inheritance picture for Yitzhak's comment :PVNV is the base for PVMG\, not plain NV. .. please check that it is correct.
His comment and your adjustment are both correct.
The bug persists in 5.8.0.
@cwest - Status changed from 'new' to 'resolved'
Migrated from rt.perl.org#16677 (status was 'resolved')
Searchable as RT16677$