Skip to content

Sqlite "Access violation" while simple upsert loop with transaction. #1467

Closed
@foriequal0

Description

@foriequal0

Envorinment

  • OS: Windows 10
  • Rust: stable 1.55.0 MSVC
  • sqlx: { version = "0.5.7", features = ["runtime-tokio-rustls", "sqlite"] }

Following code crashes while run.

use std::time::Instant;
use anyhow::Result;
use sqlx::{Connection, ConnectOptions};
use sqlx::sqlite::SqliteConnectOptions;
use rand;
use rand::Rng;

#[tokio::main]
async fn main() -> Result<()> {
    let mut conn = SqliteConnectOptions::new()
        .filename(":memory:")
        .connect().await?;

    sqlx::query(r#"
    CREATE TABLE kv (k PRIMARY KEY, v);
    CREATE INDEX idx_kv ON kv (v);
    "#).execute(&mut conn).await?;

    let mut rng = rand::thread_rng();
    for i in 0..1_000_000 {
        if i % 1_000 == 0{
            println!("{}", i);
        }
        let key = rng.gen_range(0..1_000);
        let value = rng.gen_range(0..1_000);
        let mut tx = conn.begin().await?;

        let exists = sqlx::query("SELECT 1 FROM kv WHERE k = ?")
            .bind(key)
            .fetch_optional(&mut tx)
            .await?;
        if exists.is_some() {
            sqlx::query("UPDATE kv SET v = ? WHERE k = ?")
                .bind(value)
                .bind(key)
                .execute(&mut tx)
                .await?;
        } else {
            sqlx::query("INSERT INTO kv(k, v) VALUES (?, ?)")
                .bind(key)
                .bind(value)
                .execute(&mut tx)
                .await?;
        }
        tx.commit().await?;
    }
    Ok(())
}

log:

...
176000
177000
178000
179000
Exception: Exception 0xc0000005 encountered at address 0x7ff6caea661f: Access violation reading location 0x10000003e

stacktrace:

sqlite3DbMallocRawNN(sqlite3 *,unsigned long long) sqlite3.c:28224
sqlite3DbMallocRaw(sqlite3 *,unsigned long long) sqlite3.c:28191
sqlite3VdbeMemGrow(sqlite3_value *,int,int) sqlite3.c:76723
sqlite3VdbeMemClearAndResize(sqlite3_value *,int) sqlite3.c:76765
allocateCursor(Vdbe *,int,int,int,unsigned char) sqlite3.c:86156
sqlite3VdbeExec(Vdbe *) sqlite3.c:89797
sqlite3Step(Vdbe *) sqlite3.c:84331
sqlite3_step(sqlite3_stmt *) sqlite3.c:84389
sqlx_core::sqlite::statement::worker::impl$0::new::closure$0(closure$0) worker.rs:51
std::sys_common::backtrace::__rust_begin_short_backtrace<sqlx_core::sqlite::statement::worker::impl$0::new::closure$0,tuple$<> >(closure$0) backtrace.rs:125
std::thread::impl$0::spawn_unchecked::closure$0::closure$0<sqlx_core::sqlite::statement::worker::impl$0::new::closure$0,tuple$<> >(closure$0) mod.rs:476
std::panic::impl$30::call_once<tuple$<>,std::thread::impl$0::spawn_unchecked::closure$0::closure$0>(AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>) panic.rs:347
std::panicking::try::do_call<std::panic::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>,tuple$<> >(unsigned char *) panicking.rs:401
_$LT$core..ptr..unique..Unique$LT$T$GT$$u20$as$u20$core..convert..From$LT$$RF$mut$u20$T$GT$$GT$::from::hd0746f89f6d41b16 0x00007ff6cacfc483
std::panicking::try<tuple$<>,std::panic::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0> >(AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>) panicking.rs:365
std::panic::catch_unwind<std::panic::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>,tuple$<> >(AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>) panic.rs:434
std::thread::impl$0::spawn_unchecked::closure$0<sqlx_core::sqlite::statement::worker::impl$0::new::closure$0,tuple$<> >(closure$0) mod.rs:475
core::ops::function::FnOnce::call_once<std::thread::impl$0::spawn_unchecked::closure$0,tuple$<> >(std::thread::impl$0::spawn_unchecked::closure$0 *) function.rs:227
std::sys::windows::thread::impl$0::new::thread_start() thread.rs:57
BaseThreadInitThunk 0x00007ffc15717034
RtlUserThreadStart 0x00007ffc17482651

It doesn't crash if I run it without the transaction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions