我目前正经历一个非常可怕的堆栈溢出。
fn generate_all_possible_attacks_for(
all_relevant_moves: &U64PerSquare,
number_of_all_relevant_moves: &U64PerSquare,
magic_numbers: &U64PerSquare,
calculate_attacks_for: &dyn Fn(&dyn BoardPos, u64) -> u64,
) -> Box<[U64PerSquare; 4096]> {
let mut all_attacks = Box::new([U64PerSquare::default(); 4096]);
//...
}我可以在函数本身上添加一个断点,但是就在之后(就像我在函数的第一行上放置了一个断点,或者添加了一个打印)永远不会到达,并且程序会经历堆栈溢出。
Exception thrown at 0x00007FF69C048067 in chess_ai.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000E296606000).
thread 'main' has overflowed its stack由于堆栈跟踪本身相当短,因此我怀疑堆栈上放置了一些太大的变量:
chess_ai.exe!__chkstk() Line 109 (d:\a01\_work\6\s\src\vctools\crt\vcstartup\src\misc\amd64\chkstk.asm:109)
chess_ai.exe!chess_logic::magic_bit_board::generate_all_possible_attacks_for(unsigned __int64[64] * all_relevant_moves, unsigned __int64[64] * number_of_all_relevant_moves, unsigned __int64[64] * magic_numbers, ref$<dyn$<core::ops::function::Fn<tuple$<ref$<dyn$<chess_logic::square::BoardPos>>,u64>,assoc$<Output,u64>>>>) Line 302 (c:\Users\elias\Documents\Projects\chess_ai\chess_logic\src\magic_bit_board.rs:302)
chess_ai.exe!chess_logic::magic_bit_board::generate_all_possible_rook_attacks() Line 294 (c:\Users\elias\Documents\Projects\chess_ai\chess_logic\src\magic_bit_board.rs:294)
chess_ai.exe!core::ops::function::FnOnce::call_once<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)(),tuple$<>>(unsigned __int64[4096][64] *(*)()) Line 227 (c:\rustc\fe5b13d681f25ee6474be29d748c65adcd91f69e\library\core\src\ops\function.rs:227)
chess_ai.exe!once_cell::sync::impl$11::force::closure$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>(once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>) Line 1212 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\lib.rs:1212)
chess_ai.exe!once_cell::sync::impl$6::get_or_init::closure$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>(once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>) Line 1023 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\lib.rs:1023)
chess_ai.exe!once_cell::imp::impl$4::initialize::closure$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>,enum$<once_cell::sync::impl$6::get_or_init::Void>>(once_cell::imp::impl$4::initialize::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>,enum$<once_cell::sync::impl$6::get_or_init::Void>> *) Line 85 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\imp_std.rs:85)
chess_ai.exe!core::ops::function::impls::impl$3::call_mut<tuple$<>,dyn$<core::ops::function::FnMut<tuple$<>,assoc$<Output,bool>>>>(ref_mut$<dyn$<core::ops::function::FnMut<tuple$<>,assoc$<Output,bool>>>> * self) Line 269 (c:\rustc\fe5b13d681f25ee6474be29d748c65adcd91f69e\library\core\src\ops\function.rs:269)
chess_ai.exe!once_cell::imp::initialize_or_wait(core::sync::atomic::AtomicUsize * queue, enum$<core::option::Option<ref_mut$<dyn$<core::ops::function::FnMut<tuple$<>,assoc$<Output,bool>>>>>, 1, 18446744073709551615, Some>) Line 213 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\imp_std.rs:213)
chess_ai.exe!once_cell::imp::OnceCell<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>>::initialize<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>,enum$<once_cell::sync::impl$6::get_or_init::Void>>(once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>> self) Line 81 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\imp_std.rs:81)
chess_ai.exe!once_cell::sync::OnceCell<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>>::get_or_try_init<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>,enum$<once_cell::sync::impl$6::get_or_init::Void>>(once_cell::sync::impl$6::get_or_init::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>> self) Line 1063 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\lib.rs:1063)
chess_ai.exe!once_cell::sync::OnceCell<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>>::get_or_init<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>>(once_cell::sync::impl$11::force::closure_env$0<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()> self) Line 1023 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\lib.rs:1023)
chess_ai.exe!once_cell::sync::Lazy<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>::force<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>() Line 1211 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\lib.rs:1211)
chess_ai.exe!once_cell::sync::impl$12::deref<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()>(once_cell::sync::Lazy<alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global>,alloc::boxed::Box<array$<array$<u64,64>,4096>,alloc::alloc::Global> (*)()> * self) Line 1221 (c:\Users\elias\.cargo\registry\src\github.com-1ecc6299db9ec823\once_cell-1.12.0\src\lib.rs:1221)
chess_ai.exe!chess_logic::magic_bit_board::get_rook_attacks_for(ref$<dyn$<chess_logic::square::BoardPos>> blockers, unsigned __int64) Line 48 (c:\Users\elias\Documents\Projects\chess_ai\chess_logic\src\magic_bit_board.rs:48)
chess_ai.exe!chess_ai::main() Line 19 (c:\Users\elias\Documents\Projects\chess_ai\src\main.rs:19)
chess_ai.exe!core::ops::function::FnOnce::call_once<void (*)(),tuple$<>>(void(*)()) Line 227 (c:\rustc\fe5b13d681f25ee6474be29d748c65adcd91f69e\library\core\src\ops\function.rs:227)
chess_ai.exe!std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<>>(void(*)() f) Line 125 (c:\rustc\fe5b13d681f25ee6474be29d748c65adcd91f69e\library\std\src\sys_common\backtrace.rs:125)
chess_ai.exe!std::rt::lang_start::closure$0<tuple$<>>(std::rt::lang_start::closure_env$0<tuple$<>> *) Line 145 (c:\rustc\fe5b13d681f25ee6474be29d748c65adcd91f69e\library\std\src\rt.rs:145)
[Inline Frame] chess_ai.exe!core::ops::function::impls::impl$2::call_once() Line 259 (c:\rustc\fe5b13d681f25ee6474be29d748c65adcd91f69e\library\core\src\ops\function.rs:259)有没有办法找出是什么占据了堆栈中的空间?
在尝试使用gdb进行调试时(这显然完全启动了桶)(我也是,实际上对gdb缺乏经验):
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from .\target\debug\chess_ai.exe...(no debugging symbols found)...done.
(gdb) run
Starting program: C:\Users\elias\Documents\Projects\chess_ai\target\debug\chess_ai.exe
[New Thread 29132.0x4d98]
[New Thread 29132.0x954]
[New Thread 29132.0x793c]
[New Thread 29132.0x603c]
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ff69c048067 in ?? ()
(gdb) bt
#0 0x00007ff69c048067 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)实际上,这个程序在Linux上运行得非常好(崩溃发生在windows上)。有人告诉我,Linux上的堆栈要大得多。因此,如果有任何gdb技巧来查找大型变量,我可以在Linux上这样做。
发布于 2022-06-05 00:47:38
盒式数组基本上是一个大小固定的向量,但有一个警告:当您使用Box::new([...])创建它时,数组是在堆栈上创建的,然后通过Box::new()移动到堆中,而向量的元素数据则直接在堆上创建。如果您发现自己创建了像这个这样的大型装箱数组,那么您最好使用直接在堆上分配的vec![U64PerSquare::default(); 4096]。问题很可能是,您有多个嵌套级别的函数调用来创建这些装箱数组--或者说4096 * size_of::<U64PerSquare>()已经比堆栈大了。
如果您确实想要固定大小的类型,那么有一个三步进程可以使您在不需要堆栈分配的情况下到达那里:
如果盒式切片的长度与Vec<T>.
Box<[T]>,这是一个对Box<[T; N]>来说是绝对正确的Box<[T]>。在你的例子中,看起来是这样的:
fn new_board() -> Box<[U64PerSquare; 4096]> {
vec![Default::default(); 4096]
.into_boxed_slice()
.try_into()
.unwrap()
}您可以使用泛型来概括此模式:
fn new_boxed_array<T: Clone + Default, const N: usize>() -> Box<[T; N]> {
vec![Default::default(); N]
.into_boxed_slice()
.try_into()
// Mapping the error to a string prevents the requirement T:Debug,
// and This Should Never Fail(TM) anyway.
.map_err(|_| "conversion from slice to array failed")
.unwrap()
}https://stackoverflow.com/questions/72503916
复制相似问题