occasional segfaults
by pasting this input into rodent3, i got a segfault in CBitBoard::PawnAttacks about 50% of the time:
position startpos moves d2d4 g8f6 g1f3 d7d5 c2c4 c7c6 b1c3 d5c4 a2a4 c8f5 f3e5 b8d7 e5c4 d8c7 g2g3 e7e5 d4e5 d7e5 c1f4 f6d7 f1g2 f5e6 c4e5 d7e5 e1g1 c7a5 c3e4 a8d8 d1c2 f8e7 b2b4 e7b4 c2b2 f7f6 f1b1 e8g8 f4e5 f6e5 e4g5 b4c3 b2c2 e6f5 g2e4 g7g6 c2a2 g8g7 b1b7 d8d7 a1b1 a5a6 a2b3 d7b7 b3b7 a6b7 b1b7 g7g8 e4c6 f8d8 b7a7 d8d6 c6e4 f5d7 h2h4 c3d4 a7a8 g8g7 e2e3 d4c3 e4f3
go infinite
for some memory corruption reason, the eColor value was around 32000 when the crash happened. in order to have some assistance, i compiled the binary (latest master) with address sanitizer on ubuntu linux 22.04:
# Define compiler flags
-CXXFLAGS = -g -std=c++14 -Wall -Wno-unknown-pragmas -O3 -fno-rtti -pthread $(CFG)
+CXXFLAGS = -fsanitize=address -g -std=c++14 -Wall -Wno-unknown-pragmas -O0 -g3 -fno-rtti -pthread $(CFG)
CXX1FLAGS = -g -std=c++14 -Wall -Wno-unknown-pragmas -pthread $(CFG1)
# Define linker options
-LDFLAGS = -s -Wl,--no-as-needed,--gc-sections
+LDFLAGS = -Wl,--no-as-needed,--gc-sections
LD1FLAGS = -lm
and using the above input, the binary crashes all of the time with the following report:
=================================================================
==4027073==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffcf78a
64a0 at pc 0x000000556deb bp 0x7fa8471f4d70 sp 0x7fa8471f4d68
READ of size 8 at 0x7ffcf78a64a0 thread T1
#0 0x556dea in cEngine::StartThinkThread(POS*)::'lambda'()::operator()() con
st /root/Rodent_III/sources/src/rodent.h:946:43
#1 0x556d4c in void std::__invoke_impl<void, cEngine::StartThinkThread(POS*)
::'lambda'()>(std::__invoke_other, cEngine::StartThinkThread(POS*)::'lambda'()&&
) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h
:60:14
#2 0x556cdc in std::__invoke_result<cEngine::StartThinkThread(POS*)::'lambda
'()>::type std::__invoke<cEngine::StartThinkThread(POS*)::'lambda'()>(cEngine::S
tartThinkThread(POS*)::'lambda'()&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../.
./../../include/c++/9/bits/invoke.h:95:14
#3 0x556cb4 in void std::thread::_Invoker<std::tuple<cEngine::StartThinkThread(POS*)::'lambda'()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:244:13
#4 0x556c84 in std::thread::_Invoker<std::tuple<cEngine::StartThinkThread(POS*)::'lambda'()> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:251:11
#5 0x556b5d in std::thread::_State_impl<std::thread::_Invoker<std::tuple<cEngine::StartThinkThread(POS*)::'lambda'()> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:195:13
#6 0x7fa84bc3edf3 (/lib/x86_64-linux-gnu/libstdc++.so.6+0xd6df3)
#7 0x7fa84b9fe608 in start_thread /build/glibc-LcI20x/glibc-2.31/nptl/pthread_create.c:477:8
#8 0x7fa84b8f6352 in clone /build/glibc-LcI20x/glibc-2.31/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Address 0x7ffcf78a64a0 is located in stack of thread T0 at offset 0 in frame
#0 0x55562f in std::thread::thread<ParseGo(POS*, char const*)::$_0, void>(ParseGo(POS*, char const*)::$_0&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:118
This frame has 2 object(s):
[32, 40) 'agg.tmp'
[64, 65) 'ref.tmp' (line 130)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow /root/Rodent_III/sources/src/rodent.h:946:43 in cEngine::StartThinkThread(POS*)::'lambda'()::operator()() const
Shadow bytes around the buggy address:
0x10001ef0cc40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001ef0cc50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001ef0cc60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001ef0cc70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001ef0cc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10001ef0cc90: 00 00 00 00[f1]f1 f1 f1 00 f2 f2 f2 01 f3 f3 f3
0x10001ef0cca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001ef0ccb0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x10001ef0ccc0: 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f8 f8
0x10001ef0ccd0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
0x10001ef0cce0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
Thread T1 created by T0 here:
#0 0x47f60a in pthread_create (/root/Rodent_III/sources/rodentIII+0x47f60a)
#1 0x7fa84bc3f0c9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xd70c9)
#2 0x556469 in cEngine::StartThinkThread(POS*) /root/Rodent_III/sources/src/rodent.h:946:19
#3 0x55380a in ParseGo(POS*, char const*) /root/Rodent_III/sources/src/uci.cpp:358:16
#4 0x551dae in UciLoop() /root/Rodent_III/sources/src/uci.cpp:92:13
#5 0x4ead59 in main /root/Rodent_III/sources/src/main.cpp:126:5
#6 0x7fa84b7fb082 in __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:308:16
in a build without threads using -DNO_THREADS and the following patch to make the option work again, there's no such issue. i suspect the cause is concurrent modification of global variables.
--- a/sources/src/rodent.h
+++ b/sources/src/rodent.h
@@ -70,12 +70,13 @@ static constexpr int max_tt_size_mb = 4096; // TODO: Fruit 3.2.1 uses 16384 on 6
//#define NO_THREADS
+ #define MAX_THREADS 48
+
#ifndef NO_THREADS
#include <thread>
#ifndef USE_THREADS
#define USE_THREADS
#endif
- #define MAX_THREADS 48
#else
#undef USE_THREADS
#endif
i'm reporting this because i can't make much sense of the C++ mess in the address sanitizer backtrace, but someone else might.
oh, this change is also needed for NO_THREADS support
@@ -1192,7 +1195,7 @@ void cEngine::Slowdown() {
#ifndef USE_THREADS
if ((!(Glob.nodes & 2047))
- && !Glob.is_testing
+ && !Glob.isTesting
&& mRootDepth > 1) CheckTimeout();
#endif