On Fri Oct 28, 2016 at 05:48:48PM +0700, Dan Kennedy wrote:
> On 10/28/2016 05:39 PM, no...@null.net wrote:
> > Hi Rowan,
> > 
> > On Fri Oct 28, 2016 at 06:19:59PM +0800, Rowan Worth wrote:
> > > Every sqlite_stmt you use *must* be finalized via sqlite3_finalize.
> > > I'm not exactly sure what that looks like from the other side of DBD,
> > > but I would be checking your perl code for a statement/resultset
> > > object which outlives the database connection itself.
> > >
> > Some of my new debug statements appear to confirm that: database
> > handles are being cleaned up before statement handles, even though
> > presumably the statement handle still has a reference back to the
> > database.
> 
> SQLite should handle that. If you call sqlite3_close() before all statement
> handles have been cleaned up, the call fails with SQLITE_MISUSE. Or if you
> use sqlite3_close_v2(), the call succeeds, but a reference count is used to
> ensure that the db handle object is not actually deleted until all
> statements are. close_v2() was added for this situation - where a garbage
> collectors or similar is responsible for closing db handles and finalizing
> statements.

The "handles" I was referring to above were Perl DBI handles. No doubt
they contain a real SQLite handle somewhere, but I don't think it is
safe to assume a one-to-one mapping. For example, the following appears
to create two Perl objects for each of the $db and $sth variables:

    use DBI;

    sub DBI::db::DESTROY {
        warn "DESTROY @_";
    }

    sub DBI::st::DESTROY {
        warn "DESTROY @_";
    }

    my $db = DBI->connect('dbi:SQLite:dbname=:memory:');
    my $sth = $db->prepare('select 1');


        #       DESTROY DBI::db=HASH(0x9acf68c) at x line 4.
        #       DESTROY DBI::st=HASH(0x9acf95c) at x line 8.
        #       DESTROY DBI::st=HASH(0x9acf754) at x line 8.
        #       DBI st handle 0x9acf95c has uncleared implementors data.
        #               dbih_clearcom (sth 0x9acf95c, com 0x9ad1518, imp 
DBD::SQLite::st):
        #                  FLAGS 0x100113: COMSET IMPSET Warn PrintError 
PrintWarn 
        #                  PARENT DBI::db=HASH(0x9acf600)
        #                  KIDS 0 (0 Active)
        #                  NUM_OF_FIELDS 1
        #                  NUM_OF_PARAMS 0
        #       DESTROY DBI::db=HASH(0x9acf600) at x line 4.
        #       DBI db handle 0x9acf68c has uncleared implementors data.
        #               dbih_clearcom (dbh 0x9acf68c, com 0x9ac1fd8, imp 
DBD::SQLite::db):
        #                  FLAGS 0x100317: COMSET IMPSET Active Warn PrintError
        #                        PrintWarn AutoCommit 
        #                  PARENT DBI::dr=HASH(0x9acf1a0)
        #                  KIDS 0 (0 Active)
        #

It is not obvious to me why that is so and I don't know the DBD::SQLite
code base so I won't speculate.

> If this is repeatable, try running it under valgrind. The valgrind
> error should make it pretty clear whether or not the statement handle
> really has already been finalized.

Well I have found what is probably the original source of the error: I
was keeping (Perl) statement handles around after the database handles
had expired. That doesn't mean that there isn't an issue with
how DBD::SQLite is using SQLite, but I no longer have the motivation to
track down that error when the easy answer to my problem is "don't do
that." Plus I have another error to report in a new thread :-(

Thanks everyone for listening.

-- 
Mark Lawrence
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to