marwatk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to track down a leak with Devel::GC::Helper, but I keep getting 'Can't locate auto/DBI/FIRSTKEY.al'.

Playing with the source (Helper.xs) I determined that it happens during this call:

while (val = hv_iternext_flags((HV*) sstr, HV_ITERNEXT_WANTPLACEHOLDER +S)) {

I'm not too familiar with the C side of perl, but from what I can tell DBI puts some magic on a hash (fake hash?), but doesn't implement some of the necessary iteration methods.

I've been trying to figure out how I can detect that this is about to happen and skip digging into that variable, but have been unsuccessful.

with this debug code:
warn( "gc_note_sv12.2.1" ); sv_dump( sstr ); warn( "magic follows" ); sv_dump( SvMAGIC(sstr) ); while (val = hv_iternext_flags((HV*) sstr, HV_ITERNEXT_WANTPLACEHO +LDERS)) {
the last lines of output are:

gc_note_sv12.2.1 at testhelper.pl line 13. SV = PVHV(0x9c99a30) at 0x9d19c7c REFCNT = 1 FLAGS = (RMG,SHAREKEYS) IV = 0 NV = 0 MAGIC = 0x9de2398 MG_VIRTUAL = &PL_vtbl_pack MG_TYPE = PERL_MAGIC_tied(P) MG_FLAGS = 0x02 REFCOUNTED MG_OBJ = 0x9dd7520 SV = RV(0x9cb4d30) at 0x9dd7520 REFCNT = 1 FLAGS = (ROK) RV = 0x9dd752c ARRAY = 0x0 KEYS = 0 FILL = 0 MAX = 7 RITER = -1 EITER = 0x0 magic follows at testhelper.pl line 13. SV = NULL(0x0) at 0x9de2398 REFCNT = 6251956 FLAGS = (FAKE,pNOK)
Do any of you gurus have an idea for how I can detect and skip that failure before entering the while loop?

Thanks,
Marcus

Replies are listed 'Best First'.
Re: Devel::GC::Helper + DBI (easy)
by tye (Sage) on Sep 29, 2006 at 04:41 UTC
    from what I can tell DBI puts some magic on a hash (fake hash?), but doesn't implement some of the necessary iteration methods

    I don't have that problem with my copy of DBI and I see FIRSTKEY in the most recent DBI on CPAN.

    So you might want to put some more effort into figuring out why your copy of DBI is broken (or give us more information so we can help you do that).

    Note that fixing this particular problem is likely as easy as:

    sub DBI::FIRSTKEY { () }

    which you don't even have to put inside DBI.pm. That's certainly much easier than trying to make XS code tolerant of broken modules.

    - tye        

      Hi tye,

      My DBI has DBI::FIRSTKEY as well (in the perl code, not in xs), but it doesn't seem to matter. (I've tried reinstalling the latest DBI). I even went so far as to implement FIRSTKEY in DBI.xs, which did make my error go away, but made Devel::GC::Helper get stuck in an infinite loop.

      Any other suggestions are welcome though.
        I even went so far as to implement FIRSTKEY in DBI.xs, which did make my error go away, but made Devel::GC::Helper get stuck in an infinite loop.

        If your FIRSTKEY didn't return an empty list (or undef?) then you might cause an infinite loop.

        It'd be interesting to figure out what causes this failure of not finding DBI::FIRSTKEY. You seem in a good position to do that, already having a test case and jumping into the C debugger with it. :)

        - tye        

Re: Devel::GC::Helper + DBI
by nmerriweather (Friar) on Sep 30, 2006 at 01:03 UTC

      Just today, after 2 years of DBI use w/o this problem, it pops up. Occurs during compile -- a 'use' of an application module is sufficient to set it off. 'use DBI' by itself does not trigger the problem.

      I haven't touched any of the modules associated w/ the perl installation, v. 5.8.7 from Activestate. I have been changing my application code, but the same sort of changes as usual.

      I have replaced the Perl install dir w/ a backup from a few days ago -- problem persists.

      SDE is Komodo, which has been getting into "Not Responding" mode more than usual. After adding the method to the top-level scope of DBI, the error message about not being able to locate FIRSTKEY.al goes away, BUT compile is kicked out from DBI, now with no message.

      AND: The current DBI module has the FIRSTKEY() on line 1335, below the top scope of DBI.pm; see below. The previous version of DBI, v 11.43 2004/02/01, has the same code. Adding the recommended sub DCL does not change things.

      *********************************************************** *********************************************************** # $Id: DBI.pm 6755 2006-08-06 21:21:03Z timbo $ # vim: ts=8:sw=4 # # Copyright (c) 1994-2004 Tim Bunce Ireland ... # -------------------------------------------------------------------- # === OPTIONAL MINIMAL BASE CLASSES FOR DBI SUBCLASSES === # We only define default methods for harmless functions. # We don't, for example, define a DBD::_::st::prepare() { package # hide from PAUSE DBD::_::common; # ====== Common base class methods ====== use strict; # methods common to all handle types: sub _not_impl { my ($h, $method) = @_; $h->trace_msg("Driver does not implement the $method method.\n"); return; # empty list / undef } # generic TIEHASH default methods: sub FIRSTKEY { } sub NEXTKEY { } sub EXISTS { defined($_[0]->FETCH($_[1])) } # XXX undef? sub CLEAR { Carp::carp "Can't CLEAR $_[0] (DBI)" } *********************************************************** ***********************************************************

      Code tags and formatting added by GrandFather

      Just today, after 2 years of DBI use w/o this problem, it pops up.

      Occurs during compile -- a 'use' of an application module is sufficient to set it off. 'use DBI' by itself does not trigger the problem.

      I haven't touched any of the modules associated w/ the perl installation, v. 5.8.7 from Activestate. I have been changing my application code, but the same sort of changes as usual.

      I have replaced the Perl install dir w/ a backup from a few days ago -- problem persists.

      SDE is Komodo, which has been getting into "Not Responding" mode more than usual.

      After adding the method to the top-level scope of DBI, the error message about not being able to locate FIRSTKEY.al goes away, BUT compile is kicked out from DBI, now with no message.

      AND: The current DBI module has the FIRSTKEY() on line 1335, below the top scope of DBI.pm; see below. The previous version of DBI, v 11.43 2004/02/01, has the same code. Adding the recommended sub DCL does not change things.



      ***********************************************************
      ***********************************************************

      <c>
      # $Id: DBI.pm 6755 2006-08-06 21:21:03Z timbo $
      # vim: ts=8:sw=4
      #
      # Copyright (c) 1994-2004 Tim Bunce Ireland
      ...
      #
      --------------------------------------------------------------------
      # === OPTIONAL MINIMAL BASE CLASSES FOR DBI SUBCLASSES ===

      # We only define default methods for harmless functions.
      # We don't, for example, define a DBD::_::st::prepare()
      { package # hide from PAUSE

      DBD::_::common;
      # ====== Common base class methods ======
      use strict;
      # methods common to all handle types:

      sub _not_impl {
      my ($h, $method) = @_;
      $h->trace_msg("Driver does not implement the $method
      method.\n"); return; # empty list / undef
      }
      # generic TIEHASH default methods:
      sub FIRSTKEY { }
      sub NEXTKEY { }
      sub EXISTS { defined($_[0]->FETCH($_1)) } # XXX undef?
      sub CLEAR { Carp::carp "Can't CLEAR $_[0] (DBI)" }
      ***********************************************************
      ***********************************************************
      <c/>
        RESOLVED

        The culprit was in application code: an exit() located at top-level module scope rather than inside a sub.

        I saw a similar post w/ the same symptom, but not related to DBI. So looks like this is a matter of poor perl handling of exit() during program load, rather than a bug w/ DBI.

        CPAN should be able to close bug #21112: Inheritance causes odd behavior.