1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 19:49:14 +00:00

Fix a segfault.

this patch fixes a rare but reproducible segfault observed playing a
multi-threaded match, it is discussed somewhat in fishcooking.

From the core file, it could be observed that the issue was in qsearch, namely:

````
   ss->pv[0] = MOVE_NONE;
````

and the backtrace shows the it arrives there via razoring, called from the rootNode:

````
    (gdb) bt
    alpha=-19, beta=682, depth=DEPTH_ZERO) at search.cpp:1247
````

Indeed, ss->pv can indeed by a nullptr at the rootNode. However, why is the
segfault so rare ?

The reason is that the condition that guards razoring:

````
   (depth < 2 * ONE_PLY &&  eval <= alpha - RazorMargin)
````

is almost never true, since at the root alpha for depth < 5 is -VALUE_INFINITE.

Nevertheless with the new failHigh scheme, this is not guaranteed, and rootDepth > 5,
can still result in a depth < 2 search at the rootNode. If now another thread,
via the hash, writes a new low eval to the rootPos qsearch can be entered.
Rare but not unseen... I assume that some of the crashes in fishtest recently
might be due to this.

Closes https://github.com/official-stockfish/Stockfish/pull/1860

No functional change
This commit is contained in:
Joost VandeVondele 2018-12-16 09:51:29 +01:00 committed by Stéphane Nicolet
parent fda0161e3a
commit 4e2bb8fa44

View file

@ -303,6 +303,7 @@ void MainThread::search() {
void Thread::search() { void Thread::search() {
Stack stack[MAX_PLY+7], *ss = stack+4; // To reference from (ss-4) to (ss+2) Stack stack[MAX_PLY+7], *ss = stack+4; // To reference from (ss-4) to (ss+2)
Move pv[MAX_PLY+1];
Value bestValue, alpha, beta, delta; Value bestValue, alpha, beta, delta;
Move lastBestMove = MOVE_NONE; Move lastBestMove = MOVE_NONE;
Depth lastBestMoveDepth = DEPTH_ZERO; Depth lastBestMoveDepth = DEPTH_ZERO;
@ -314,6 +315,7 @@ void Thread::search() {
std::memset(ss-4, 0, 7 * sizeof(Stack)); std::memset(ss-4, 0, 7 * sizeof(Stack));
for (int i = 4; i > 0; i--) for (int i = 4; i > 0; i--)
(ss-i)->continuationHistory = &this->continuationHistory[NO_PIECE][0]; // Use as sentinel (ss-i)->continuationHistory = &this->continuationHistory[NO_PIECE][0]; // Use as sentinel
ss->pv = pv;
bestValue = delta = alpha = -VALUE_INFINITE; bestValue = delta = alpha = -VALUE_INFINITE;
beta = VALUE_INFINITE; beta = VALUE_INFINITE;
@ -756,8 +758,9 @@ namespace {
} }
// Step 7. Razoring (~2 Elo) // Step 7. Razoring (~2 Elo)
if ( depth < 2 * ONE_PLY if ( !rootNode // The required rootNode PV handling is not available in qsearch
&& eval <= alpha - RazorMargin) && depth < 2 * ONE_PLY
&& eval <= alpha - RazorMargin)
return qsearch<NT>(pos, ss, alpha, beta); return qsearch<NT>(pos, ss, alpha, beta);
improving = ss->staticEval >= (ss-2)->staticEval improving = ss->staticEval >= (ss-2)->staticEval