Description
Steps to reproduce
- Have a godot-rust library, a Godot project, and the two linked together with the gdextension file for both debug and release builds.
- Have a custom node type in the Rust library with an
#[export] other: Option<Gd<Node>>
value. Print its value in the ready function. - Build the Rust library for release build and delete any debug build outputs.
- Open the Godot project, place a custom node, and any other node. Set up the custom node value to point to the other node.
- Delete the .godot folder if it was present from an earlier run.
- Export the Godot project in release configuration. Run the binary and observe that the Rust library panics at unwrapping the empty reference value.
System information
Reproduced in a clean minimal project with Godot v4.2.1 on Windows, but I saw it in a normal project in v4.3-dev5 and on Linux too. Tried with gdext@e7cc36 (2024-04-15).
To make sure that it's only the Option<Gd<Node>>
that doesn't get its value initialized I added another field with a primitive type like #[export] value: i32
set to non-zero value in the project and that indeed prints its proper value.
Expected output
(From a release build where debug build was also present.)
PS C:\Users\lostlont\Desktop\godot-rust-test\build\windows\release> .\godot-rust-test.exe
PS C:\Users\lostlont\Desktop\godot-rust-test\build\windows\release> Initialize godot-rust (API v4.2.stable.official, runtime v4.2.1.stable.official)
Godot Engine v4.2.1.stable.official.b09f793f5 - https://godotengine.org
Vulkan API 1.3.260 - Forward+ - Using Vulkan Device #0: AMD - Radeon (TM) RX 470 Graphics
value: 42
other.name: TestNode2
value: 43
other.name: TestNode
Actual output
PS C:\Users\lostlont\Desktop\godot-rust-test\build\windows\release> .\godot-rust-test.exe
PS C:\Users\lostlont\Desktop\godot-rust-test\build\windows\release> Initialize godot-rust (API v4.2.stable.official, runtime v4.2.1.stable.official)
Godot Engine v4.2.1.stable.official.b09f793f5 - https://godotengine.org
Vulkan API 1.3.260 - Forward+ - Using Vulkan Device #0: AMD - Radeon (TM) RX 470 Graphics
value: 42
thread '<unnamed>' panicked at src\lib.rs:43:14:
called `Option::unwrap()` on a `None` value
stack backtrace:
0: 0x7ffb13af97aa - std::backtrace_rs::backtrace::dbghelp::trace::hacfb2290d6f041d8
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\..\..\backtrace\src\backtrace/dbghelp.rs:131:5
1: 0x7ffb13af97aa - std::backtrace_rs::backtrace::trace_unsynchronized::hdfe81743a1a02ed5
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\..\..\backtrace\src\backtrace/mod.rs:66:5
2: 0x7ffb13af97aa - std::sys_common::backtrace::_print_fmt::h7ba8ff6eb3450b74
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\sys_common/backtrace.rs:68:5
3: 0x7ffb13af97aa - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h419f3866c85fe1bf
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\sys_common/backtrace.rs:44:22
4: 0x7ffb13b489ad - core::fmt::rt::Argument::fmt::hefb4ad2f61213328
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\core\src\fmt/rt.rs:142:9
5: 0x7ffb13b489ad - core::fmt::write::h81c90b6a84eba5be
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\core\src\fmt/mod.rs:1120:17
6: 0x7ffb13aefbdd - std::io::Write::write_fmt::h216459b0e40bea5d
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\io/mod.rs:1846:15
7: 0x7ffb13af95d3 - std::sys_common::backtrace::_print::h4508c4e8cc70e1aa
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\sys_common/backtrace.rs:47:5
8: 0x7ffb13af95d3 - std::sys_common::backtrace::print::hea1734d8b31113d5
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\sys_common/backtrace.rs:34:9
9: 0x7ffb13afc309 - std::panicking::default_hook::{{closure}}::ha8fd0cbe9cc21e6f
10: 0x7ffb13afc008 - std::panicking::default_hook::hd35fa15eba4e74a2
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src/panicking.rs:292:9
11: 0x7ffb13afca0f - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::ha685e7d47afbfbfb
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\alloc\src/boxed.rs:2029:9
12: 0x7ffb13afca0f - std::panicking::rust_panic_with_hook::hca0c0de800db3c83
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src/panicking.rs:785:13
13: 0x7ffb13afc881 - std::panicking::begin_panic_handler::{{closure}}::he773c37bd73058bd
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src/panicking.rs:651:13
14: 0x7ffb13af9f49 - std::sys_common::backtrace::__rust_end_short_backtrace::hff55a16a8c27989e
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src\sys_common/backtrace.rs:171:18
15: 0x7ffb13afc606 - rust_begin_unwind
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\std\src/panicking.rs:647:5
16: 0x7ffb13b44fb7 - core::panicking::panic_fmt::h678ed93bf965ebf9
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\core\src/panicking.rs:72:14
17: 0x7ffb13b45072 - core::panicking::panic::h7b26555fedc35695
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\core\src/panicking.rs:144:5
18: 0x7ffb13b44ce8 - core::option::unwrap_failed::heba8ea2599e810c6
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library\core\src/option.rs:1978:5
19: 0x7ffb1305ea75 - <godot_rust_test::TestNode as godot_core::obj::traits::cap::ImplementsGodotVirtual>::__virtual_call::function::h5a4012fbff537f2d
20: 0x7ff75d5d07c4 - <unknown>
21: 0x7ff75b521c34 - <unknown>
22: 0x7ff75b521be4 - <unknown>
23: 0x7ff75b556cbe - <unknown>
24: 0x7ff75a804336 - <unknown>
25: 0x7ff75dd0ab23 - <unknown>
26: 0x7ff75a7c12ee - <unknown>
27: 0x7ff75a7c13e6 - <unknown>
28: 0x7ffbce707344 - <unknown>
29: 0x7ffbcf3426b1 - <unknown>
fatal runtime error: failed to initiate panic, error 5
Note that the actual dll copied to the exported folder is the proper release configuration library. It just looks like that references are not initialized when the debug library is not present.
I have the feeling that it's expected to have a debug build of the godot-rust library always, as opening the project in the editor also shows missing components without it, however the export itself seem to be capable of handling the types and primitives of the library so I'd think that it's just malfunctioning right now. Also this may not be a normal use case in the editor, but in CI build pipelines it would be normal to have only a release build job, without any debug build artifacts.
Thank you very much