Subject: pkg/37267: jemalloc(?) crash fixes for games/xfrisk
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <dholland@eecs.harvard.edu>
List: pkgsrc-bugs
Date: 11/02/2007 22:35:01
>Number:         37267
>Category:       pkg
>Synopsis:       some crash fixes for games/xfrisk
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 02 22:35:00 +0000 2007
>Originator:     David A. Holland <dholland@eecs.harvard.edu>
>Release:        NetBSD 4.99.31 (pkgsrc of 20071014)
>Organization:
>Environment:
System: NetBSD tanaqui 4.99.31 NetBSD 4.99.31 (TANAQUI) #19: Tue Sep 11 19:46:35 EDT 2007 dholland@tanaqui:/usr/src/sys/arch/i386/compile/TANAQUI i386
Architecture: i386
Machine: i386
>Description:

xfrisk has never been the most stable program, but last night I
started getting cores from the bot daemons; this is new behavior,
perhaps jemalloc fallout.

So I dug around a little and in the course of trying to catch the
cores in gdb, tripped first on another problem, which was causing
memory corruption; fixing it seems to have made the cores go away.

There are two patches below; the first fixes things so turning on
xfrisk's debugging code doesn't result in an immediate SIGSEGV on
startup, and the second fixes a bug that causes dialogs to pop up
saying "Bogus call to CARDS_RenderCard!". The latter may or may
not be the same as the historic known bug with similar symptoms.
As previously noted, the second patch also stops the core dumps
that I've started getting.

These patches should be sent upstream, but it doesn't appear that
there's any way to do so at the moment. Let me know if this changes.
In the meantime I've stuck them where I used to keep my old xfrisk
patches.

>How-To-Repeat:

Start a game going with 11 (seems to be the max allowed) computer
players. After a while one or both of the computer player daemons will
crash out. If you play in the game yourself you'll probably see the
dialogs.

>Fix:

Patch #1:

This patch fixes some stuff that breaks if you compile with assertions
and debugging on.

--- findtypes.c~	1999-11-13 16:58:31.000000000 -0500
+++ findtypes.c	2007-11-02 14:49:44.000000000 -0400
@@ -77,12 +77,12 @@
   fprintf(file, "/* Pointer type */\n");
   
   /* Find the types */
-  if (sizeof(void *) == sizeof (int))
-    pointerType = "int";
-  else if (sizeof(void *) == sizeof(long int))
-    pointerType = "long int";
-  else if (sizeof(void *) == sizeof(short int))
-    pointerType = "short int";
+  if (sizeof(void *) == sizeof (unsigned))
+    pointerType = "unsigned";
+  else if (sizeof(void *) == sizeof(long unsigned))
+    pointerType = "long unsigned";
+  else if (sizeof(void *) == sizeof(short unsigned))
+    pointerType = "short unsigned";
   else
     {
       printf("Cannot find integer the size of a pointer on this machine.\n");
--- viewStats.c~	2000-01-16 13:47:02.000000000 -0500
+++ viewStats.c	2007-11-02 14:58:28.000000000 -0400
@@ -632,7 +632,7 @@
       break;
   
   /* There MUST be a slot */
-  D_Assert(iSlot >= MAX_PLAYERS, "Whoa, dude!  Bogus player somewhere?!");
+  D_Assert(iSlot < MAX_PLAYERS, "Whoa, dude!  Bogus player somewhere?!");
   
   /* Actually dump the data to the slot */
   STAT_RenderSlot(iSlot, iPlayer);


   ------

Patch #2:

This patch fixes at least one set of "Bogus call to CARDS_RenderCard"
problems - the problem being that if the card deck runs out, the server
starts handing out card -1.

I don't know if this is the same problem we used to see back in the
day or a different one.

--- server.c~	2000-01-02 17:52:17.000000000 -0500
+++ server.c	2007-11-02 15:33:03.000000000 -0400
@@ -427,11 +427,17 @@
 
     case MSG_REQUESTCARD: {
         MsgRequestCard *pMess = (MsgRequestCard *)pvMessage;
+	Int32 iCard;
+
+	iCard = DECK_GetCard(pCardDeck);
+	if (iCard < 0) {
+	    break;
+	}
 
         RISK_SetCardOfPlayer(pMess->iPlayer,
                              RISK_GetNumCardsOfPlayer
                              (pMess->iPlayer),
-                             DECK_GetCard(pCardDeck));
+                             iCard);
         RISK_SetNumCardsOfPlayer(pMess->iPlayer,
                                  RISK_GetNumCardsOfPlayer
                                  (pMess->iPlayer)+1);