From 0f12d4e815364608302e3c20026a0826ac4bf85e Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Tue, 17 Mar 2026 01:59:20 +0900 Subject: [PATCH] Ensure Close always removes runtime finalizer to prevent memory leak Fixes #1319 --- sqlite3.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/sqlite3.go b/sqlite3.go index d69f649..dffc2bd 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -1783,15 +1783,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { // Close the connection. func (c *SQLiteConn) Close() error { + c.mu.Lock() + defer c.mu.Unlock() + if c.db == nil { + return nil + } + runtime.SetFinalizer(c, nil) rv := C.sqlite3_close_v2(c.db) if rv != C.SQLITE_OK { - return c.lastError() + return lastError(c.db) } deleteHandles(c) - c.mu.Lock() c.db = nil - c.mu.Unlock() - runtime.SetFinalizer(c, nil) return nil } @@ -1932,16 +1935,18 @@ func (s *SQLiteStmt) Close() error { return nil } s.closed = true - if !s.c.dbConnOpen() { + runtime.SetFinalizer(s, nil) + conn := s.c + stmt := s.s + s.s = nil + s.c = nil + if !conn.dbConnOpen() { return errors.New("sqlite statement with already closed database connection") } - rv := C.sqlite3_finalize(s.s) - s.s = nil + rv := C.sqlite3_finalize(stmt) if rv != C.SQLITE_OK { - return s.c.lastError() + return conn.lastError() } - s.c = nil - runtime.SetFinalizer(s, nil) return nil }