gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnugo-devel] NNGS crash


From: Gunnar Farneback
Subject: [gnugo-devel] NNGS crash
Date: Thu, 06 Dec 2001 22:14:05 +0100
User-agent: EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/20.7 (sparc-sun-solaris2.7) (with unibyte mode)

If you go to the page with recent game records for GNU Go games on
NNGS,

http://www.lysator.liu.se/~gunnar/gnugo/nngs/

you will see that two recent games (actually the same one twice) is
marked in bold face with the text Crash. This means that the game was
adjourned because the GNU Go engine crashed. I have also modified the
list so that adjourned games are only stored for three days, ordinary
games for a week, "interesting" games for a month, and crashes until
manually removed. "Interesting" games are defined as 19x19 games
against a *-rated opponent, where the rating difference and the
handicap mismatches with at least two stones and the misfavored player
won. I.e. games which can be assumed to have a significant effect on
the rating, for good or for bad. These games are marked with a
boldface result. The most recent example is a nine stone game where
GNU Go lost against pooo [9k*].

The crashed game was a segmentation fault in dragon_escape(). This is
a fairly serious bug, which can cause memory corruption and no end of
problems, although I believe it's quite rare that it has any visible
effect at all. The position where the crash came is fairly extreme, as
you can see if you download it. Anyway, the appended patch fixes the
bug and adds an assertion to detect it if it should get reintroduced.

/Gunnar

Index: engine/dragon.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.34
diff -u -r1.34 dragon.c
--- engine/dragon.c     2001/12/04 20:26:07     1.34
+++ engine/dragon.c     2001/12/06 21:08:57
@@ -1419,6 +1419,7 @@
        if (distance == 0) {
          if (board[SOUTH(ii)] == EMPTY
              && board[WEST(ii)] == EMPTY
+             && !mx[SW(ii)]
              && (board[SW(ii)] == color
                  || (board[SW(ii)] == color
                      && ON_BOARD(SOUTH(SW(ii)))
@@ -1429,6 +1430,7 @@
                      
          if (board[WEST(ii)] == EMPTY
              && board[NORTH(ii)] == EMPTY
+             && !mx[NW(ii)]
              && (board[NW(ii)] == color
                  || (board[NW(ii)] == color
                      && ON_BOARD(WEST(NW(ii)))
@@ -1439,6 +1441,7 @@
                      
          if (board[NORTH(ii)] == EMPTY
              && board[EAST(ii)] == EMPTY
+             && !mx[NE(ii)]
              && (board[NE(ii)] == color
                  || (board[NE(ii)] == color
                      && ON_BOARD(NORTH(NE(ii)))
@@ -1449,6 +1452,7 @@
                      
          if (board[EAST(ii)] == EMPTY
              && board[SOUTH(ii)] == EMPTY
+             && !mx[SE(ii)]
              && (board[SE(ii)] == color
                  || (board[SE(ii)] == color
                      && ON_BOARD(EAST(SE(ii)))
@@ -1462,8 +1466,14 @@
   }
 
   /* Reset used mx cells. */
-  for (k = 0; k < queue_end; k++)
+  for (k = 0; k < queue_end; k++) {
+    /* The assertion fails if the same element should have been queued
+     * twice, which might happen if ENQUEUE() is called without
+     * checking mx[].
+     */
+    ASSERT1(mx[queue[k]] == 1, queue[k]);
     mx[queue[k]] = 0;
+  }
 
   return escape_potential;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]