db.serialize() crashes in recent Electron versions
The serialize() function doesn't work due to V8 sandboxing?
[23992:0508/184214.301:ERROR:node_bindings.cc(162)] Fatal error in V8: v8_ArrayBuffer_NewBackingStore When the V8 Sandbox is enabled, ArrayBuffer backing stores must be allocated inside the sandbox address space. Please use an appropriate ArrayBuffer::Allocator to allocate these buffers, or disable the sandbox.
"electron": "^35.3.0",
"better-sqlite3": "^11.10.0",
MVR:
private initializeInMemoryDatabase(dbPath: string, isNewGame: boolean = false): void {
log.info('Initializing database at path: ', dbPath)
let tempDB: Database = new Database(dbPath)
const buffer = tempDB.serialize()
log.info('Database buffer created')
}
I don't want to backup the db, but serialize it and open it as a new db, that I can then write to/read from without writing to the backing file until I choose to. This is for a game, so imagine a video game that has a "save" button, at which point the game saves certain data to the db.
This was working fine on electron 28.2.0, but broke upon updating to the latest version. The DB is not in WAL mode.
For reference, it seems the solution is posted here, but hasn't been merged: https://github.com/WiseLibs/better-sqlite3/pull/1036#issuecomment-2227422329
@malshoff have you validated that solution? If so, can you put up a PR?
I'm testing it right now, and I'll definitely put up a PR if it works.
NICE! Thanks for the effort.
Know that I can’t merge your PR, but I can gently prod those who can.
I spent way more time than was probably necessary since I don't really deal much with native node modules and their associated complexities, but I got the fix to work locally. The flag being read was just wrong, as @Prinzhorn speculated. This works properly:
#src
#if defined(V8_ENABLE_SANDBOX)
// When V8 Sandbox is enabled (in newer Electron versions), we need to use Buffer::Copy
// instead of Buffer::New to ensure the ArrayBuffer backing store is allocated inside the sandbox
static inline v8::MaybeLocal<v8::Object> BufferSandboxNew(v8::Isolate* isolate, char* data, size_t length, void (*finalizeCallback)(char*, void*), void* finalizeHint) {
v8::MaybeLocal<v8::Object> buffer = node::Buffer::Copy(isolate, data, length);
finalizeCallback(data, finalizeHint);
return buffer;
}
#define SAFE_NEW_BUFFER(env, data, length, finalizeCallback, finalizeHint) BufferSandboxNew(env, data, length, finalizeCallback, finalizeHint)
#else
// When V8 Sandbox is not enabled, we can use the more efficient Buffer::New
#define SAFE_NEW_BUFFER(env, data, length, finalizeCallback, finalizeHint) node::Buffer::New(env, data, length, finalizeCallback, finalizeHint)
#endif
#end
Tested using
npm run lzz
npx prebuild -t 35.3.0 -r electron --include-regex 'better_sqlite3.node$'
electron-rebuild only builds from remote apparently, it won't rebuild locally changed packages (from my little experience with it at least), so I used that prebuild command and it properly built the module for electron 35.3.0.
I will check out the contributing guide and make a PR for this, but I wanted to leave this here on the chance that I get busy with something else and don't make a PR soon.
This can be closed I assume?
This can be closed I assume?
Yes