Very strange Bug

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Very strange Bug

Post by Desperado »

Code: Select all


if((attackR(KING(black),OCCUPIED) & bF1)) {codeblock}

- attackR is returning (unsigned __int64)
- bF1 is static const ui64_t

The problem is the following: in my 64 bit compile (MS Express VS2008).
the codeblock is entered although the Attackgetter returns 0, when 0 is the correct value.

Code: Select all


The original code snippet looks like this.

 // oo+ , ooo+
 if((pos->cst & oow)  && (attackR(KING(black),OCCUPIED) & bF1)) {generate_oow(pos,mli);}
 if((pos->cst & ooow) && (attackR(KING(black),OCCUPIED) & bD1)) {generate_ooow(pos,mli);}

Now, i have tested the most important things.The only way to get rid of the problem
is to cast the expression explicit into an int-type. But of course that should not be necessary.

I am really out of ideas (done so far):
- results checked
- types checked
- moved code around
- checked expressions by its own
- ... , ... , ...

if you like i can include the statement into a seperate function and give you an assembly.
Or i can output what i cannot believe myself, the boolean result==1 although the bitboard
returns 0... i think i am going crazy here.

am i too blind to see sth. very obvious. Ideas are welcome

thx, Michael
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Very strange Bug

Post by hgm »

What happens when you do this:

Code: Select all

 // oo+ , ooo+
 __int64 x=-1, y=-1;
 if((pos->cst & oow)  && ((x=attackR(KING(black),OCCUPIED)) & bF1)) {generate_oow(pos,mli);}
 if((pos->cst & ooow) && ((y=attackR(KING(black),OCCUPIED)) & bD1)) {generate_ooow(pos,mli);}

printf("# x=%x y=%x\n", x, y);
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Very strange Bug

Post by Desperado »

hgm wrote:What happens when you do this:

Code: Select all

 // oo+ , ooo+
 __int64 x=-1, y=-1;
 if((pos->cst & oow)  && ((x=attackR(KING(black),OCCUPIED)) & bF1)) {generate_oow(pos,mli);}
 if((pos->cst & ooow) && ((y=attackR(KING(black),OCCUPIED)) & bD1)) {generate_ooow(pos,mli);}

printf("# x=%x y=%x\n", x, y);
Hello hgm,

your code shows a different behaviour than the original one. But
at the and i am also able to catch statements where y==0 entered the
codeblock. (i simply ran my perft collection).

This changes under the following conditions:

if i use the temporary values in the codeblock , everything works like
it should (at least i cannot get any exceptions).
Independant if i use ui64_t z, or si64_t x,y.
Independant if initialized them or not.

Here is how it works, beside the explicit typecast.

Code: Select all


  // oo+ , ooo+ 

 __int64 x=-1,y=-1;

 if((pos->cst & oow)  && ((x=attackR(KING(black),OCCUPIED)) & bF1)) {if(x==0)printPosition(pos);generate_oow(pos,mli);} 

 if((pos->cst & ooow) && ((y=attackR(KING(black),OCCUPIED)) & bD1)) {if(y==0)printPosition(pos);generate_ooow(pos,mli);} 
Michael
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Very strange Bug

Post by hgm »

It sounds like attackR does not really return the type that the compiler thinks it returns. I don't know if you are doing 32 or 64-bit compiles, but in 32-bit mode errors like this could occur because the compiler thinks a 64-bit value is returned in a register pair (usually EAX:EDX), while in fact the routine returns only a 32-bit value in EAX, with some random left-over from another calculation still hanging in EDX.
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Very strange Bug

Post by Desperado »

I _only_ get this error in 64 bit compile. Sth. known about implicit
type cast problems of 64bit values into boolean type, or some c/c++ issues ? What to do when compiler strikes somehow ?

if i should post my attackGetter Modul, i will do. I simply
want to understand what can be wrong here !?!
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Very strange Bug

Post by Desperado »

The thing with "random left-over" i have checked somehow i would
say, because i already moved the code snippet posted to other
sections and the result was that always at the same point the same
error occured.
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Very strange Bug

Post by hgm »

That is not really conclusive, as the 'random left-over' could be put there by attackR, which would make it always the same no matter where you move this code. Furthermore, a random left-over is unlikely to be zero, even if it woud be different all the time.

If you want to get to the bottom of this, you could try to simplify the attackR routine to one that only does 'return 0;', and your main program to one that only does the two code-lines you posted, and then see if the error still occurs. If it does, you could compile to assembler, and post the assembly code generated for attackR(), and for main(), so we can see what is done wrong, and if the compiler is to blame for this.
Karlo Bala
Posts: 373
Joined: Wed Mar 22, 2006 10:17 am
Location: Novi Sad, Serbia
Full name: Karlo Balla

Re: Very strange Bug

Post by Karlo Bala »

Desperado wrote:

Code: Select all


if((attackR(KING(black),OCCUPIED) & bF1)) {codeblock}

- attackR is returning (unsigned __int64)
- bF1 is static const ui64_t

The problem is the following: in my 64 bit compile (MS Express VS2008).
the codeblock is entered although the Attackgetter returns 0, when 0 is the correct value.

Code: Select all



The original code snippet looks like this.

 // oo+ , ooo+
 if((pos->cst & oow)  && (attackR(KING(black),OCCUPIED) & bF1)) {generate_oow(pos,mli);}
 if((pos->cst & ooow) && (attackR(KING(black),OCCUPIED) & bD1)) {generate_ooow(pos,mli);}

Now, i have tested the most important things.The only way to get rid of the problem
is to cast the expression explicit into an int-type. But of course that should not be necessary.

I am really out of ideas (done so far):
- results checked
- types checked
- moved code around
- checked expressions by its own
- ... , ... , ...

if you like i can include the statement into a seperate function and give you an assembly.
Or i can output what i cannot believe myself, the boolean result==1 although the bitboard
returns 0... i think i am going crazy here.

am i too blind to see sth. very obvious. Ideas are welcome

thx, Michael
As far as I know Express edition can not compile for 64 bit platform
Best Regards,
Karlo Balla Jr.
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Very strange Bug

Post by Desperado »

Karlo Bala wrote:
Desperado wrote:

Code: Select all


if((attackR(KING(black),OCCUPIED) & bF1)) {codeblock}

- attackR is returning (unsigned __int64)
- bF1 is static const ui64_t

The problem is the following: in my 64 bit compile (MS Express VS2008).
the codeblock is entered although the Attackgetter returns 0, when 0 is the correct value.

Code: Select all



The original code snippet looks like this.

 // oo+ , ooo+
 if((pos->cst & oow)  && (attackR(KING(black),OCCUPIED) & bF1)) {generate_oow(pos,mli);}
 if((pos->cst & ooow) && (attackR(KING(black),OCCUPIED) & bD1)) {generate_ooow(pos,mli);}

Now, i have tested the most important things.The only way to get rid of the problem
is to cast the expression explicit into an int-type. But of course that should not be necessary.

I am really out of ideas (done so far):
- results checked
- types checked
- moved code around
- checked expressions by its own
- ... , ... , ...

if you like i can include the statement into a seperate function and give you an assembly.
Or i can output what i cannot believe myself, the boolean result==1 although the bitboard
returns 0... i think i am going crazy here.

am i too blind to see sth. very obvious. Ideas are welcome

thx, Michael
As far as I know Express edition can not compile for 64 bit platform
It can. It requires a sdk update and some other minimal configuration steps.
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Very strange Bug

Post by Desperado »

hgm wrote:That is not really conclusive, as the 'random left-over' could be put there by attackR, which would make it always the same no matter where you move this code. Furthermore, a random left-over is unlikely to be zero, even if it woud be different all the time.

If you want to get to the bottom of this, you could try to simplify the attackR routine to one that only does 'return 0;', and your main program to one that only does the two code-lines you posted, and then see if the error still occurs. If it does, you could compile to assembler, and post the assembly code generated for attackR(), and for main(), so we can see what is done wrong, and if the compiler is to blame for this.
Thx so far, all i can say for now is that i have introduced a

extern __inline ui64_t attackRTest(sq_t,ui64_t); function.

I tried : - return(constant 0)
- return(EXP == 0), so the compiler may not optimize sth. here.

i have added the function, so i can run my perft collection with about 12 billion nodes, which by the way doesnt produce any error. That indicates
that my attack routines are working.

But unfortunatelly returning 0 does not lead to any kind of exception.
Even if this line of code takes 2 weeks to solve, i will get the answer :shock: :?
Maybe the register usage is now different or whatever...

I fear there are more bugs of this kind, i only catched it here
because i rewrite my movgen which i am intensively testing therefore.
The equivalent code for black, does not produce any exceptions for example.

What do you think of, if i work around with sth like

#define BOOL64(EXP) ((int)(EXP))

Basically i dont like such workarounds, but it would do the job
and i would be on the safe side ?!

Michael