Out of Memory is triggered if using Rust Local Thread Storage (LTS)
Rustc version: redox-2025-01-12
after cookbook!560 (merged)
A simple compilation with test.rs
in dev config with rustc will trigger allocation until the kernel triggers OOM
user:~$ rustc test.rs
thread 'rustc' panicked at /mnt/redox/cookbook/recipes/dev/rust/source/library/std/src/thread/local.rs:272:26:
cannot access a Thread Local Storage value during or after destruction: AccessError
error: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
note: please make sure that you have updated to the latest nightly
note: please attach the file at `/home/user/rustc-ice-2025-07-25T06_46_42-75.txt` to your bug report
query stack during panic:
KERNEL PANIC: panicked at src/memory/mod.rs:1017:34:
not yet implemented: oom
FP ffff800027f2fca0: PC ffffffff80029f32
FFFFFFFF80029DE0+0152
rust_begin_unwind
FP ffff800027f2fd80: PC ffffffff800a2a5f
FP ffff800027f2fdb0: PC ffffffff800488bd
FP ffff800027f2fe20: PC ffffffff8008f830
FFFFFFFF8008F7F0+0040
kernel::arch::x86_64::interrupt::exception::page::inner
FP ffff800027f2ff50: PC ffffffff80083117
FFFFFFFF800830E0+0037
kernel::arch::x86_64::interrupt::exception::page
0000000ab5555ffe: GUARD PAGE
CPU #0, CID 0xffffff7f80032210
NAME: /usr/bin/rustc, DEBUG ID: 88
HALT
The error source mentions source/library/std/src/thread/local.rs:272
, which is:
/// Acquires a reference to the value in this TLS key.
///
/// This will lazily initialize the value if this thread has not referenced
/// this key yet.
///
/// # Panics
///
/// This function will `panic!()` if the key currently has its
/// destructor running, and it **may** panic if the destructor has
/// previously been run for this thread.
///
/// # Examples
///
/// ```
/// thread_local! {
/// pub static STATIC: String = String::from("I am");
/// }
///
/// assert_eq!(
/// STATIC.with(|original_value| format!("{original_value} initialized")),
/// "I am initialized",
/// );
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn with<F, R>(&'static self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
self.try_with(f).expect( // <-------------------------------
"cannot access a Thread Local Storage value \
during or after destruction",
)
}
I cannot obtain the backtrace, hence I don't know what f
is passed here.
Fortunately, we can disable LTS as it's also not available in all platform. To disable it, we can turn it off at: source/compiler/rustc_target/src/spec/base/redox.rs
:
pub(crate) fn opts() -> TargetOptions {
TargetOptions {
os: "redox".into(),
env: "relibc".into(),
dynamic_linking: true,
families: cvs!["unix"],
has_rpath: true,
position_independent_executables: true,
relro_level: RelroLevel::Full,
has_thread_local: false, // <--------- set this to false
crt_static_default: true,
crt_static_respected: true,
crt_static_allows_dylibs: true,
late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"]),
..Default::default()
}
}
Edited by Wildan Mubarok