libsql-client-ts icon indicating copy to clipboard operation
libsql-client-ts copied to clipboard

'transactions' example segmentation fault on windows x64

Open s4s0l opened this issue 7 months ago • 1 comments

Running examples/transactions example in a loop results in segfault on windows.

If I run many transactions in a loop, they all succeed no matter how many transactions there are. But if you leave node running afterwards for a while, it will crush. It happens only when loop is long. Above 1000 iterations it happens all the time.

Segfault handler gives me this:

00007FFCCA739D06 (ntdll): (filename not available): RtlWow64GetCurrentCpuArea
00007FFCCA73A10E (ntdll): (filename not available): RtlWow64GetCurrentCpuArea
00007FFCCA86003E (ntdll): (filename not available): KiUserExceptionDispatcher
00007FFC3346D854 (index): (filename not available): napi_register_module_v1
00007FFC331B3FA2 (index): (filename not available): napi_register_module_v1
00007FFC33315ED2 (index): (filename not available): napi_register_module_v1
00007FFC32F3B602 (index): (filename not available): (function-name not available)
00007FFC32F17A2C (index): (filename not available): (function-name not available)
00007FFC32F33054 (index): (filename not available): (function-name not available)
00007FF7E5081024 (node): (filename not available): node_module_register
00007FF7E5081FA7 (node): (filename not available): node_module_register
00007FF7E50984D2 (node): (filename not available): v8::base::CPU::has_popcnt
00007FF7E5082610 (node): (filename not available): node_module_register
00007FF7E50D1300 (node): (filename not available): node_api_throw_syntax_error
00007FF7E50B6ADD (node): (filename not available): node_api_throw_syntax_error
00007FF7E5142151 (node): (filename not available): uv_pipe_pending_type
00007FF7E514E9FD (node): (filename not available): uv_run
00007FF7E511F125 (node): (filename not available): node::SpinEventLoop
00007FF7E4FF010A (node): (filename not available): X509_STORE_get_cleanup
00007FF7E508CB23 (node): (filename not available): node::Start
00007FF7E508B907 (node): (filename not available): node::Start
00007FF7E4DAE51C (node): (filename not available): AES_cbc_encrypt
00007FF7E68275B8 (node): (filename not available): inflateValidate
00007FFCC90EE8D7 (KERNEL32): (filename not available): BaseThreadInitThunk
00007FFCCA7B14FC (ntdll): (filename not available): RtlUserThreadStart
/c/nvm4w/nodejs/npm: line 65:  7834 Segmentation fault      "$NODE_EXE" "$NPM_CLI_JS" "$@"

I'm not capable enough to compile libsql with debug symbols, but maybe someone else would have an idea what libsql is doing here.

Tested with : libsql 0.4.6 & 0.5.4. Node 22.12.0 / 22.14.0 / 18.20.8 / 23.11.0.

On linux (x86_64) it does not crush.

Source example here
import { createClient } from "@libsql/client";
// stack trace
// requires "segfault-handler": "^1.3.0"
// import pkg from 'segfault-handler';
// const { registerHandler } = pkg;
// registerHandler('segfault-crush.log');
const client = createClient({
    url: "file:local.db",
});
await client.batch(
    [
        "DROP TABLE IF EXISTS users",
        "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)",
        "INSERT INTO users (name) VALUES ('Iku Turso')",
    ],
    "write",
);
const names = ["John Doe", "Mary Smith", "Alice Jones", "Mark Taylor"];
let secondTransaction;

// for 400 it does not crush
// above 1000 it crushes always
// but all the transactions are committed ok
const theAmount = 1000;
try {
    for(let i = 0; i < theAmount; i++){

        secondTransaction = await client.transaction("write");
        for (const name of names) {
            await secondTransaction.execute({
                sql: "INSERT INTO users (name) VALUES (?)",
                args: [name],
            });
        }   
        await secondTransaction.commit();
        if (i % 100 === 0)
        console.log("user " + i + " added successfully")
    }
} catch (e) {
    console.error(e);
    await secondTransaction?.rollback();
}
const result = await client.execute("SELECT * FROM users");
console.log("Users:", result.rows.length); 
await new Promise(resolve => setTimeout(resolve, 10000)); // it will segfault here.
console.log("Done");

s4s0l avatar Apr 04 '25 14:04 s4s0l