Help request for debugging ICS

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Help request for debugging ICS

Post by syzygy »

hgm wrote:It was compiled with -g .
Then upgrading gdb is probably the easiest way to get rid of it (if necessary).
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Help request for debugging ICS

Post by hgm »

Well, I hope it is not necessary. It was difficult enough to get this gdb on the machine. And for now we are still running without a crash.
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Help request for debugging ICS

Post by hgm »

With no crashes in a 9-round tourney with 12 participants, a 9-round tourney with 24 participants, and continuous playing of 5 simultaneous games all day in between, it seems that the cause of the frequent ICS crashes indeed has been fixed. At least good enough toplan a new 'official' tourney for next Saturday. (Announcement will follow later this week.)

Thanks everybody for the help and advice; I could not have done it without that!
Ed Trice
Posts: 100
Joined: Fri Sep 19, 2014 5:03 am

Re: Help request for debugging ICS

Post by Ed Trice »

If the -1 is an unsigned declaration, it will pass in the maximum positive value as an index. Usually such a large index would be way beyond the intended range.
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Help request for debugging ICS

Post by hgm »

That would have been better, because it would guarantee a segfault always, and the original developers would never have left in this bug. But it was declared as an int:

Code: Select all

GENSTRUCT struct game {
	/* Not saved in game file */
	int revertHalfMove;
	int totalHalfMoves;
	int white;
	int black;
	int link;
	enum gamestatus status;
	int examHalfMoves;
	int examMoveListSize;  
	struct move_t *examMoveList; _LEN(examMoveListSize)    /* extra movelist for examine */

	unsigned startTime;    /* The relative time the game started  */
	unsigned lastMoveTime; /* Last time a move was made */
	unsigned lastDecTime;  /* Last time a players clock was decremented */
	int flag_pending;
	int wTimeWhenReceivedMove;
	int wTimeWhenMoved;
	int bTimeWhenReceivedMove;
	int bTimeWhenMoved;
	int wLastRealTime;
	int wRealTime;
	int bLastRealTime;
	int bRealTime;

	/* this is a dummy variable used to tell which bits are saved in the structure */
	unsigned not_saved_marker;
  
	/* Saved in the game file */
	enum gameend result;
	int winner;
	int wInitTime, wIncrement;
	int bInitTime, bIncrement;
	time_t timeOfStart;
	unsigned flag_check_time;
	int wTime;
	int bTime;
	int clockStopped;
	int rated;
	int private;
	enum gametype type;
	int passes; /* For simul's */
	int numHalfMoves;
	int moveListSize; /* Total allocated in *moveList */
	struct move_t *moveList; _LEN(moveListSize)      /* primary movelist */
	char FENstartPos[74]; _NULLTERM   /* Save the starting position. */
	struct game_state_t game_state;
	
	char white_name[MAX_LOGIN_NAME]; _NULLTERM   /* to hold the playername even after he disconnects */        
	char black_name[MAX_LOGIN_NAME]; _NULLTERM   
	int white_rating;
	int black_rating;
	char variant[80]; // [HGM] arbitrary variant name for sending to interface, derived from load-directory name
};

GENSTRUCT struct game_globals {
	int g_num;
	struct game *garray; _LEN(g_num)
};
EXTERN struct game_globals game_globals;

  struct game *gg = &game_globals.garray[g];
  int gl = gg->link;
The gg->link field is supposed to hold the number (index in game_globals.garray) of the bughouse partner game in bughouse, or a -1 if there is no partner game.

So if gl== -1 then game_globals.garray[gl].white always grabs something reasonably far before game_globals (as the "struct game" elements of the latter are pretty big), but probably still within valid memory. What it finds there, however, can vary, and is then used as an index in

player_globals.parray[???].b_stats.rating

This memory access is likely what caused the segfault. I tried to figure it out with gdb from the core dump, but gdb was insisting that game_globals.garray was not an array.
Ed Trice
Posts: 100
Joined: Fri Sep 19, 2014 5:03 am

Re: Help request for debugging ICS

Post by Ed Trice »

Is there a call to MemSet() anywhere for the global? Sometimes array declarations left in the global space can't grab all they need until it's too late (runtime vs. initialization).

Example:

memset(global_array_name_without_brackets, 0, sizeof(global_array_name_without_brackets));
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Help request for debugging ICS

Post by hgm »

I thought in C it is guaranteed that uninitialized global variables start with value 0. So if the OS does ot guarantee this behavior on loading an executable image, the memset must be hidden somewhere in the startup code that eventually calls main().
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: Help request for debugging ICS

Post by JoshPettus »

Uninitialized global variables? I think my C++ programming teacher would die simply so she could role in her grave.

The only global variables were were allowed to use were static global constants. XD
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Help request for debugging ICS

Post by syzygy »

JoshPettus wrote:Uninitialized global variables? I think my C++ programming teacher would die simply so she could role in her grave.
Instead of dying she should take a copy of any C or C++ standard and study it.

Apparently the usual implementation consists of the compiler allocating memory for uninitialised global variables in the .bss section and the OS clearing that area at load or (on-demand) allocation time. (Of course the standard does not care how it is implemented.)
Ed Trice
Posts: 100
Joined: Fri Sep 19, 2014 5:03 am

Re: Help request for debugging ICS

Post by Ed Trice »

hgm wrote:I thought in C it is guaranteed that uninitialized global variables start with value 0. So if the OS does ot guarantee this behavior on loading an executable image, the memset must be hidden somewhere in the startup code that eventually calls main().
Nooooooo... There is no such guarantee.

Declare

unsigned short global_list[225000];

Then see what global_list[213210] is without any initialization.

Just because you say you want 225000 elements at 2-bytes each doesn't mean you get them.

It's just 225000 memory locations, which can contain anything from 0 to 65535 until memory is allocated for the base address starting at global_list[0] once you call malloc() or better yet, calloc().