Stream: beginners

Topic: ✔ webserver sqlite segfault


view this post on Zulip Prokop Randacek (May 18 2025 at 13:09):

Hi! :D

I'm trying to setup a sqlite inside my basic-webserver based application but i'm getting a segfault at runtime with no extra information. I'm pretty sure i'm doing something bad in the init:

init! : {} => Result Model _
init! = |_|
    db_path = Env.var!("DB_PATH") ? |err| ServerErr("DB_PATH not set: ${Inspect.to_str(err)}")

    create_command = "CREATE TABLE responses (id INTEGER PRIMARY KEY AUTOINCREMENT, time INTEGER, ip TEXT, lat DOUBLE, lng DOUBLE, type INTEGER, comment TEXT)"

    existing_create_command =
        Sqlite.query!(
            {
                path: db_path,
                query: "SELECT sql FROM sqlite_schema WHERE type='table' AND name='responses';",
                bindings: [],
                row: Sqlite.str("sql"),
            },
        )
        ? |err| ServerErr("Failed to select from sqlite schemas: ${Inspect.to_str(err)}")

    if existing_create_command != create_command then
        Err(ServerErr("DB already contains responses table and it has a bad shape"))
    else
        select_stmt =
            Sqlite.prepare!(
                {
                    path: db_path,
                    query: "SELECT * FROM responses;",
                },
            )
            ? |err| ServerErr("Failed to prepare sqlite statement: ${Inspect.to_str(err)}")

        insert_stmt =
            Sqlite.prepare!(
                {
                    path: db_path,
                    query: "INSERT INTO responses (time, ip, lat, long, type, comment) VALUES (:time, :ip, :lat, :long, :type, :comment);",
                },
            )
            ? |err| ServerErr("Failed to prepare sqlite statement: ${Inspect.to_str(err)}")

        Ok({ select_stmt, insert_stmt })

I'm trying to check that there is a table that I expect and then prepare two statements that I want to use later. I was going to add creating the new table if it is not there yet but I got stuck on this.

Is there something obvious i'm missing? Thanks for any help! :D

Full code is here: https://git.sr.ht/~prokop/mapform/tree/f773abdd1e52650e2565bdf29c3cc2089a2a52d7/item/main.roc

view this post on Zulip Brendan Hansknecht (May 18 2025 at 15:53):

Hmm. Definitely a basic webserver bug:

main(4165,0x1ecdfc840) malloc: *** error for object 0x1009d4000: pointer being freed was not allocated
main(4165,0x1ecdfc840) malloc: *** set a breakpoint in malloc_error_break to debug
Process 4165 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x0000000183453720 libsystem_kernel.dylib`__pthread_kill + 8
libsystem_kernel.dylib`__pthread_kill:
->  0x183453720 <+8>:  b.lo   0x183453740    ; <+40>
    0x183453724 <+12>: pacibsp
    0x183453728 <+16>: stp    x29, x30, [sp, #-0x10]!
    0x18345372c <+20>: mov    x29, sp
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x0000000183453720 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x000000018348bf70 libsystem_pthread.dylib`pthread_kill + 288
    frame #2: 0x0000000183398908 libsystem_c.dylib`abort + 128
    frame #3: 0x00000001832a1e38 libsystem_malloc.dylib`malloc_vreport + 896
    frame #4: 0x00000001832a59bc libsystem_malloc.dylib`malloc_report + 64
    frame #5: 0x00000001832c4144 libsystem_malloc.dylib`find_zone_and_free + 528
    frame #6: 0x0000000100007494 main`___lldb_unnamed_symbol21408 + 16
    frame #7: 0x0000000100061f0c main`___lldb_unnamed_symbol21642 + 584
    frame #8: 0x000000010004694c main`Host_sqlite_reset!_a45290bef5734ad62afcaea912ebb28a88fcce6265e83e5ce118554fa9b23df6 + 48
    frame #9: 0x000000010004a760 main`Sqlite_reset!_7caba61bebab67ae1a3d5e6f4932f5086371aaa834774ba7fe45103dc45036 + 28
    frame #10: 0x000000010005e79c main`Sqlite_query_prepared!_3ef0be3dc434ba1162e39580a72ad0387348f7e2ac5c485921af9f85a731eea + 388
    frame #11: 0x0000000100047040 main`Sqlite_query!_7b73be30696c7fe3ed242ca4629f76c2f696011d9271def91eeffdd89e9134d + 492
    frame #12: 0x000000010005a20c main`#UserApp_init!_8ea48f352d7289114fe202e56461de528fa632d8a6cda9163cba5554b08a8b + 564
    frame #13: 0x000000010005d6f4 main`_init_for_host!_e95211bde2283defe545e72d738137b8d7082e1cb419ffde6603c1dfde96f + 32
    frame #14: 0x000000010005d9f4 main`roc__init_for_host_1_exposed + 16
    frame #15: 0x000000010011c26c main`rust_main + 44
    frame #16: 0x000000018310c274 dyld`start + 2840

view this post on Zulip Brendan Hansknecht (May 18 2025 at 16:03):

I just tested with basic-webserver built from source and everything works as expected

view this post on Zulip Brendan Hansknecht (May 18 2025 at 16:04):

I wonder if we have a fix that just hasn't been released yet

view this post on Zulip Anthony Bullard (May 18 2025 at 16:05):

https://github.com/roc-lang/basic-webserver/issues/106

view this post on Zulip Anthony Bullard (May 18 2025 at 16:05):

hasn't been released

view this post on Zulip Brendan Hansknecht (May 18 2025 at 16:09):

Or, this fix: https://github.com/roc-lang/basic-webserver/issues/104

view this post on Zulip Brendan Hansknecht (May 18 2025 at 16:09):

But yeah, we need a new release of basic webserver

view this post on Zulip Prokop Randacek (May 18 2025 at 20:41):

Alright. I will be looking forward for the next releaste then :D

view this post on Zulip Notification Bot (May 18 2025 at 20:41):

Prokop Randacek has marked this topic as resolved.

view this post on Zulip Anton (May 19 2025 at 09:06):

Brendan Hansknecht said:

But yeah, we need a new release of basic webserver

It's a high priority TODO for me, there are a bunch of exposed functions without tests, so I want to add tests for those before releasing.

view this post on Zulip Anton (May 19 2025 at 09:11):

@Prokop Randacek if you want, you can build the latest version from source with:

git clone https://github.com/roc-lang/basic-webserver.git
cd basic-webserver
nix develop
roc build.roc
roc examples/hello-web.roc --linker=legacy

Last updated: Jul 06 2025 at 12:14 UTC