Skip to content

rand is not seeded, causing duplicated symbol names if two crates use gdext #1202

Open
@0x53A

Description

@0x53A

I got this in my latest wasm build:

  = note: emcc: warning: you no longer need to pass DISABLE_EXCEPTION_CATCHING or DISABLE_EXCEPTION_THROWING when using Wasm exceptions [-Wemcc]
          emcc: warning: -sSIDE_MODULE + pthreads is experimental [-Wexperimental]
          wasm-ld: error: duplicate symbol: __godot_rust_registrant_1804289383_846930886
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/rustato_lib.rustato_lib.2a01942f4ef8670f-cgu.10.rcgu.o
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/libgdext_coroutines-2531917a701074db.rlib(gdext_coroutines-2531917a701074db.gdext_coroutines.79646587b8d7f0e1-cgu.0.rcgu.o)
          
          wasm-ld: error: duplicate symbol: __godot_rust_registrant_1681692777_1714636915
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/rustato_lib.rustato_lib.2a01942f4ef8670f-cgu.10.rcgu.o
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/libgdext_coroutines-2531917a701074db.rlib(gdext_coroutines-2531917a701074db.gdext_coroutines.79646587b8d7f0e1-cgu.0.rcgu.o)
          
          wasm-ld: error: duplicate symbol: __godot_rust_registrant_1957747793_424238335
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/rustato_lib.rustato_lib.2a01942f4ef8670f-cgu.10.rcgu.o
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/libgdext_coroutines-2531917a701074db.rlib(gdext_coroutines-2531917a701074db.gdext_coroutines.79646587b8d7f0e1-cgu.0.rcgu.o)
          
          wasm-ld: error: duplicate symbol: __godot_rust_registrant_719885386_1649760492
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/rustato_lib.rustato_lib.2a01942f4ef8670f-cgu.10.rcgu.o
          >>> defined in /__w/RustedArmor/RustedArmor/rust/target/wasm32-unknown-emscripten/release/deps/libgdext_coroutines-2531917a701074db.rlib(gdext_coroutines-2531917a701074db.gdext_coroutines.79646587b8d7f0e1-cgu.0.rcgu.o)
          emcc: error: '/emsdk/upstream/bin/wasm-ld @/tmp/emscripten_7at1a7qg.rsp.utf-8' failed (returned 1)

(I am using https://github.com/0x53A/gdext_coroutines/tree/dev)

Looking at where __godot_rust_registrant comes from, I found this:

https://github.com/godot-rust/gdext/blame/551c16496d07430dd762cf26d4f4fdc72bf08c06/godot-macros/src/ffi_macros.rs#L22-L31

    // Create sufficiently unique identifier without entire `uuid` (let alone `rand`) crate dependency.
    let a = unsafe { libc::rand() };
    let b = unsafe { libc::rand() };

    let function_name = format_ident!("__godot_rust_registrant_{a}_{b}");

According to the man pages, rand must be explicitly seeded before use:

       The srand() function sets its argument as the seed for a new
       sequence of pseudo-random integers to be returned by rand().
       These sequences are repeatable by calling srand() with the same
       seed value.

       If no seed value is provided, the rand() function is automatically
       seeded with a value of 1.

So, two crates are using gdext, rand is not seeded and therefore deterministic, they both generate the same constant name.

This can be further confirmed by googling for "1804289383" (the first number of the first conflict, which leads to https://stackoverflow.com/questions/66181627/what-is-default-seed

glibc's PRNG also happens to turn a seed of 1 into a next value of 1804289383.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugc: wasmWebAssembly export target

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions