Moderator: Andres Valverde
Pedro Castro wrote:In this position, wac 237, Black receive a value of mate -9999 (- MATE) in depth 15 and 1:10 s, which is impossible, if I am not in check, is my turn, I cannot receive mate. Then, program crash.
r5k1/pQp2qpp/8/4pbN1/3P4/6P1/PPr4P/1K1R3R b - - 0 1
[diag]r5k1/pQp2qpp/8/4pbN1/3P4/6P1/PPr4P/1K1R3R b - - 0 1 [/diag]
11484945<1:1 109 0 364 c2h2 g5e4
11484945<1:2 104 0 1615 c2h2 g5e4 f5e4 b7e4
11484975<1:3 89 3 14825 c2h2 g5e4 f5e4 b7e4
11484995<1:3 -34 5 23250 f7e8 b7d5 g8f8 d4e5 c2h2
11485065<1:4 -43 12 64838 f7e8 b7b3 g8f8 g5e6 f8g8 e6c7 c2c4 b1a1
11485255<1:5 -58 31 218461 f7e8 b7b3 g8f8 g5e6 f8g8 e6c7 c2c4 b1a1
11485465<1:5 -92 52 379071 c2c5 b1a1 f7d5 b7a8 d5a8 d4c5 e5e4
11485746<1:6 -107 80 588679 c2c5 b1a1 f7d5 b7a8 d5a8 d4c5 e5e4
11486006<1:6 -108 107 799582 c2c5 b1a1 f7d5 b7a8 d5a8 d4c5 f5g4 d1f1
11486587<1:7 -94 165 1242843 c2c5 b1a1 f7d5 b7a8 d5a8 d4c5 f5c2 d1f1 e5e4
11487398<1:8 -79 245 1859457 c2c5 b1a1 f7d5 b7a8 d5a8 d4c5 f5c2 d1f1 e5e4
11487588<1:8 7 264 1987146 c2c5 b1a1 f7d5 b7d5 c5d5 d4e5 d5e5 h1f1 a8e8 h2h3
11489631<1:9 12 469 3627470 c2c5 b1a1 f7d5 b7d5 c5d5 d4e5 d5e5 h1e1 a8e8 e1e5 e8e5
11495019<1:10 27 1007 7838004 c2c1 b1a1 f7d5 b7d5 c5d5 d4e5 d5e5 h1e1 a8e8 e1e5 e8e5
11495039<1:10 177 1010 7848223 c2c1 b1a1 f7d5 b7d5 c5d5 d4e5 d5e5 h1e1 a8e8 e1e5 e8e5
I have seen in some program that limits ply, ej TSCP
if (ply > MAX_PLY - 1)
return eval();
This continues failing for my, the peculiar thing is that if I do
if (ply > MAX_PLY/2 - 1)
the thing works well.
Tord Romstad wrote:I have seen in some program that limits ply, ej TSCP
if (ply > MAX_PLY - 1)
return eval();
This continues failing for my, the peculiar thing is that if I do
if (ply > MAX_PLY/2 - 1)
the thing works well.
Very strange. Is it possible that you try to access some array with MAX_PLY elements, and that your array index is accidentally incremented and decremented by 2 rather than 1 when you make and unmake moves?
At any rate, it sounds like you have an array out of bounds bug somewhere. If your C compiler supports some kind of optional bounds checking, switch it on, recompile your program, and run WAC237 again.
Dieter B?r?ner wrote:Tord Romstad wrote:I have seen in some program that limits ply, ej TSCP
if (ply > MAX_PLY - 1)
return eval();
This continues failing for my, the peculiar thing is that if I do
if (ply > MAX_PLY/2 - 1)
the thing works well.
Very strange. Is it possible that you try to access some array with MAX_PLY elements, and that your array index is accidentally incremented and decremented by 2 rather than 1 when you make and unmake moves?
At any rate, it sounds like you have an array out of bounds bug somewhere. If your C compiler supports some kind of optional bounds checking, switch it on, recompile your program, and run WAC237 again.
I just grepped for MAXPLY in my sources. Several parts depend on MAXPLY, not only the PV. At first glance I saw killer moves, move list and several internal Yace specific tables. One would also need to take care of filling the PV after a hash cutoff. I use an end marker in several arrays (like the ones used for the PV), so one has to be aware of that additional entry needed for the endmarker (and also make sure, that the endmarker is always there, which might not be the case, when just returning eval).
It should be a good idea, to always (in debug mode) check PV moves for legality. One could also plug in such code, at the time, any move is written to the PV array, not only when actually formating it for output. This way, one should be able to find the spot of the problem easier (with the help of a debugger).
For Gcc there are "bounds checking patches". Unfortunately, they are not in the mainline source, also they only work for C and not for C++ (but they work well with mixed C and C++ programs in the C modules). It is quite a bit of work, to install and use such a bounds checking gcc (especially, when you want to use it in parallel to an unpatched gcc). I have used it under Linux. Did anybody try to apply the bounds checking patches for MinGW, Cygwin or DJGPP? Does it work under these environments. How to setup it? Are even binaries available?
Are there any other free (say as in free beer) choices available for a C compiler running under Windows or DOS (with DOS extender), that have bounds checking features. I am aware of libraries, that can check malloced memory, but they seem to miss out of bounds array accesses?
Regards,
Dieter
/* Untested, just typed into the post - I hope, I got it right */
#include <stdio.h>
void bug(int *, int * int *); /* Forword declaration, so that the compiler probably will not see the problem (when not optimizing) by source code analysis */
int main(void)
{
int a[2], b[2], c[2];
bug(a,b,c);
printf("%d %d %d %d %d %d\n", a[0], a[1], b[0], b[1], c[0], c[1]);
return 0;
}
void bug(int *a, int *b, int *c)
{
int i;
a[0]=a[1]=c[0]=c[1]=0;
for (i=-2; i<4; i++)
b[i] = i; /* out of bounds array access */
}
Dann Corbit wrote:Without bounds checker, I get this:
Run-Time Check Failure #2 - Stack around the variable 'c' was corrupted.
I will try a run with BoundsChecker also.
Dieter B?r?ner wrote:Dann Corbit wrote:Without bounds checker, I get this:
Run-Time Check Failure #2 - Stack around the variable 'c' was corrupted.
I will try a run with BoundsChecker also.
Thanks, Dann. Seems I assumed too much. I assumed, that the stack layout will be either 8 bytes for each of a, b and c. In this order, or just in reverse order. Seems the compiler reordered this. I guess, my intention was clear. I wanted to have an out of bounds array access, that probably does not anything harmful (in the sense accessing memory, not available) at runtime. You certainly can find a similar example, that should work in the sense I mean.
The question is, will bounds checker detect out of bounds array accesses in general. The array might be local, static, static inside a function or global. Detecting simple out of bounds accesses for malloced memory is much easier by a tailored malloc() with some fence at the start and at the end. that is initialized to some magic values.
You certainly also detected my typo, where one "," is missing in the prototype for bug.
How did you compile the program (which compiler options), to detect the stack corruption?
Regards,
Dieter
Dieter B?r?ner wrote:Tom, can you or anybody else try this program with valgrind:
- Code: Select all
/* Untested, just typed into the post - I hope, I got it right */
#include <stdio.h>
void bug(int *, int * int *); /* Forword declaration, so that the compiler probably will not see the problem (when not optimizing) by source code analysis */
int main(void)
{
int a[2], b[2], c[2];
bug(a,b,c);
printf("%d %d %d %d %d %d\n", a[0], a[1], b[0], b[1], c[0], c[1]);
return 0;
}
void bug(int *a, int *b, int *c)
{
int i;
a[0]=a[1]=c[0]=c[1]=0;
for (i=-2; i<4; i++)
b[i] = i; /* out of bounds array access */
}
I thought to remember, that valgrind cannot detect such problems. Gcc with bounds checking patches detects it.
Can anybody try the code with boundschecker (?) under Windows?
Regards,
Dieter
/* module a */
int a[2]; /* In one module, more global vars before and after a in the actual memory layout */
/* module b */
extern int a[];
void foo(void)
{
a[2] = 0;
}
Dieter B?r?ner wrote:Tom, so bounds checker will reliably find out of bounds array accesses (when the arrays are not malloced)? I assume you checked for the thing, that happened on Dann's computer, where probably the memory layout of a,b,c was reorderd. When b is not in the middle, it might be easier to find the problem.
Any idea, how bounds checker works? As I understand, it is an addon to MSVC. Does it change code generation? I have a hard time, to see how a pure addon can detect these things ... Valgrind "works" as expected in this case. It does not do anything to the code generation.
b[2] = 0;
may produce some code like
mov 0 to offset 8 after the adress pointed to by b
If this is a valid adress, how should an addon detect, that the adress does not belong to object b?
Does bounds checker detect simple:
- Code: Select all
/* module a */
int a[2]; /* In one module, more global vars before and after a in the actual memory layout */
/* module b */
extern int a[];
void foo(void)
{
a[2] = 0;
}
Regards,
Dieter
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 4 guests