Skip to content

sqlite: prevent reentrant statement finalization from callbacks #64795

Description

@trivikr

Version

main

Platform

macOS 26.5.2

Subsystem

sqlite

What steps will reproduce the bug?

import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync(':memory:');

db.function('close_database', () => {
  console.log('callback: closing database');
  db.close();
  console.log('callback: database closed');
});

console.log('before query');
db.prepare('SELECT close_database()').get();
console.log('after query');

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

close() should reject or defer finalization while statement execution depth is non-zero; db.deserialize() should apply the same protection.

What do you see instead?

before query
callback: closing database
callback: database closed
Segmentation fault

db.close() finalizes the prepared statement while that same statement is executing inside sqlite3_step(), and the process subsequently crashes.

Additional information

No response

Metadata

Metadata

Assignees

Labels

sqliteIssues and PRs related to the SQLite subsystem.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions