TampliteSK / dragonrose

Weak UCI-compliant chess engine written in C. Based on VICE chess engine by Richard Allbert (Bluefever Software).
GNU General Public License v3.0
2 stars 0 forks source link

compile problems solved, but game crash #4

Closed tissatussa closed 3 months ago

tissatussa commented 3 months ago

I successfully compiled the source code of your current main branch on Linux, after newest commit 8913743, but i had to adjust a few things .. while compiling i got some errors but i could solve all of them by just removing 'inline' from this function definition in 'evaluate.c' :

inline int16_t evaluate_pawn_structure(const S_BOARD *pos, uint8_t pawn_sq, uint8_t col) {
    (...)
}

besides that i had only 1 warning :

$ gcc-13 -o dragonrose *.c -lm
perft.c: In function ‘PerftTest’:
perft.c:59:57: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘uint64_t’ {aka ‘long unsigned int’} [-Wformat=]
   59 |         printf("\nTest Complete : %ld nodes visited in %dms\n",leafNodes,GetTimeMs() - start);
      |                                                        ~^                ~~~~~~~~~~~~~~~~~~~
      |                                                         |                            |
      |                                                         int                          uint64_t {aka long unsigned int}
      |                                                        %ld

So i added the 'l' char ..

As you see i compiled with a simple gcc command in src/. Your Cmake construct gave too many errors i couldn't solve (without editting the CMakeLists.txt etc.) .. i add the '-lm' argument to 'activate' math functions like 'fmin()' .. this was 1 of the problems with cmake and make : it seems the '-lm' is missing .. how were you able to compile without it ?

It created a valid binary :

$ ./dragonrose 
uci
id name Dragonrose 0.28
id author Tamplite Siphron Kents
option name Hash type spin default 64 min 4 max 65536
option name Threads type spin default 1 min 1 max 1
option name Book type check default false
uciok
quit
Segmentation fault (core dumped)

but the 'quit' command is not handled properly ..

then it played a game in CuteChess GUI, but it crashed in a nice 5m+3s game after move 26 .. here's the log tail :

<ElephantGambit v0.7.0(10): info score cp 57 depth 3 nodes 3896 time 63 pv g8g4 a1c1 e8g6
<ElephantGambit v0.7.0(10): info score cp 52 depth 4 nodes 72172 time 1049 pv e8f7 e2c2 f5e3 c2f2
<ElephantGambit v0.7.0(10): info score cp 52 depth 5 nodes 408448 time 6231 pv e8f7 e2c2 f5e3 c2f2 d8d3
<ElephantGambit v0.7.0(10): bestmove e8f7
>Dragonrose v0.28(9): position startpos moves d2d4 b8c6 g1f3 e7e6 e2e4 d7d5 e4e5 f7f6 c1f4 g7g5 f4g3 g5g4 f3d2 c6d4 c2c3 d4c6 f1b5 h7h5 h2h3 f6f5 h3g4 f5g4 e1g1 c8d7 f1e1 g8h6 c3c4 d5d4 d2e4 f8e7 e4f6 e7f6 e5f6 d8f6 b5c6 b7c6 g3e5 f6f8 d1d4 h6f5 d4d3 h8g8 b1d2 g4g3 f2g3 f8c5 g1h2 e8c8 d2f3 d7e8 d3e2 e8f7
>Dragonrose v0.28(9): isready
<Dragonrose v0.28(9): readyok
>Dragonrose v0.28(9): go wtime 56773 btime 100179 winc 3000 binc 3000
<Dragonrose v0.28(9): bestmove ŕŕ
>Dragonrose v0.28(9): isready
>ElephantGambit v0.7.0(10): isready
<Dragonrose v0.28(9): readyok
<ElephantGambit v0.7.0(10): readyok

CuteChess displayed : +0.52/5 7.4s, White makes an illegal move: ŕŕ

Btw. it's called v0.28 !?

TampliteSK commented 3 months ago

Weird, I tested it on Ubuntu recently and it wasn't getting compiler errors, except the warning you got which I have fixed locally. What errors did you get? About the -lm thing, I have it added in the makefile but I'm not sure how to add that in CMake. Thanks for notifying me about it though. I haven't encountered the segfault bug for quit, which is quite weird. I'll have to look into that because the code looks fine to me. As for the illegal move bug it's been a while for a long time but I was never able to reproduce it myself. It looks like the commands in that log seemeed to reproduce the bug for me, thanks. Will be helpful for debugging. It is supposed to be 0.28 due to new features but I seem to be creating quite a few bugs so I haven't released it yet.

tissatussa commented 3 months ago

about the illegal move ŕŕ : those are weird characters .. your program should never output those, something's clearly wrong here.

don't mind the errors i got, there were many and of all kinds and they pointed me in a wrong direction when trying to solve them. You didn't create the CMakeLists.txt properly, why not stick to my simple gcc command ? Because your code isn't yet complicated, using cmake seems bloated.

TampliteSK commented 3 months ago

Maybe just keep the makefile?

tissatussa commented 3 months ago

Maybe just keep the makefile?

yes, a hand-written Makefile will be sufficient, skip the cmake process for now.

TampliteSK commented 3 months ago

Located the "quit" segfault bug. It appears I have accidentally made it free the hashtable twice.

TampliteSK commented 3 months ago

It appears the illegal move bug was due to careless mistake of mine. I updated the time management earlier but forgot to change a number... Fixed now.

tissatussa commented 3 months ago

[ sorry to re-open this Issue ]

i get this error :

$ make
gcc-13 src/attack.c src/bitboards.c src/board.c src/data.c src/endgame.c src/evaluate.c src/hashkeys.c src/init.c src/io.c src/main.c src/makemove.c src/misc.c src/movegen.c src/perft.c src/polybook.c src/polykeys.c src/pvtable.c src/search.c src/uci.c src/validate.c -o Dragonrose -march=native -lm
/usr/bin/ld: /tmp/ccYLwhB6.o: in function `EvalPosition':
evaluate.c:(.text+0xc58): undefined reference to `is_material_draw'
/usr/bin/ld: evaluate.c:(.text+0xd56): undefined reference to `evaluate_pawn_structure'
/usr/bin/ld: evaluate.c:(.text+0xe8e): undefined reference to `evaluate_pawn_structure'
collect2: error: ld returned 1 exit status
make: *** [makefile:20: all] Error 1

i can solve this by adding this line to defs.h, just like you did for other functions in evaluate.c :

extern int16_t evaluate_pawn_structure(const S_BOARD *pos, uint8_t pawn_sq, uint8_t col);

but then same error type occurs here :

$ make
gcc-13 src/attack.c src/bitboards.c src/board.c src/data.c src/endgame.c src/evaluate.c src/hashkeys.c src/init.c src/io.c src/main.c src/makemove.c src/misc.c src/movegen.c src/perft.c src/polybook.c src/polykeys.c src/pvtable.c src/search.c src/uci.c src/validate.c -o Dragonrose -march=native -lm
/usr/bin/ld: /tmp/cczDfbk9.o: in function `EvalPosition':
evaluate.c:(.text+0xe47): undefined reference to `is_material_draw'
collect2: error: ld returned 1 exit status
make: *** [makefile:20: all] Error 1

and i also solved it by such line in defs.h : no more warnings or errors, but ..

$ make
gcc-13 src/attack.c src/bitboards.c src/board.c src/data.c src/endgame.c src/evaluate.c src/hashkeys.c src/init.c src/io.c src/main.c src/makemove.c src/misc.c src/movegen.c src/perft.c src/polybook.c src/polykeys.c src/pvtable.c src/search.c src/uci.c src/validate.c -o Dragonrose -march=native -lm

$ ./Dragonrose 
Segmentation fault (core dumped)

i have no clue, all code seems well ..

TampliteSK commented 3 months ago

It should only be externed in defs.h if it's to be used elsewhere, but in this case both functions are only declared and used within evaluate.c. Maybe try adding static in front of both functions? (Edit: And also remove the externs in defs.h) The weird thing is that I'm not getting those errors locally, might be because I'm using Windows.

tissatussa commented 3 months ago

Adding 'static' (like i find in some of your other function constructs) doesn't help, i also used a debugger :

$ make
gcc-13 src/attack.c src/bitboards.c src/board.c src/data.c src/endgame.c src/evaluate.c src/hashkeys.c src/init.c src/io.c src/main.c src/makemove.c src/misc.c src/movegen.c src/perft.c src/polybook.c src/polykeys.c src/pvtable.c src/search.c src/uci.c src/validate.c -o Dragonrose -march=native -lm

$ ./Dragonrose 
Segmentation fault (core dumped)

$ lldb-17 ./Dragonrose 
(lldb) target create "./Dragonrose"
Current executable set to '/home/roelof/Compiled/dragonrose-main-commit-6401fe6/Dragonrose' (x86_64).
(lldb) run
Process 59031 launched: '/home/roelof/Compiled/dragonrose-main-commit-6401fe6/Dragonrose' (x86_64)
Process 59031 stopped
* thread #1, name = 'Dragonrose', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x0)
    frame #0: 0x00007ffff7d02c7b libc.so.6`fclose@@GLIBC_2.2.5 at iofclose.c:48:9
(lldb) exit
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n]

Also without 'static' lldb gives the error "signal SIGSEGV: address not mapped to object".

I can try more suggestions. I'm not on Windows, it should work on all (?) OS ..

tissatussa commented 3 months ago

i'm a bit new to these compile issues, but i know a linker is ALSO involved, and i had trouble with versions not being right / compatible, which caused all kinds of errors .. which linker should be used ? How can i know / change my OS config for this ?

tissatussa commented 3 months ago

More info from another well-known debugger :

$ gdb ./Dragonrose 
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
(...)
Reading symbols from ./Dragonrose...
(No debugging symbols found in ./Dragonrose)
(gdb) run
Starting program: /home/roelof/Compiled/dragonrose-main-commit-6401fe6/Dragonrose 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7d02c7b in _IO_new_fclose (fp=0x0) at ./libio/iofclose.c:48
48      ./libio/iofclose.c: No such file or directory.
TampliteSK commented 3 months ago

The debug outputs are kinda cryptic, aside from the fact both detected segfault. Maybe I'll try on Ubuntu VM and see how it goes.

tissatussa commented 3 months ago

Are those debuggers known to you ? I just tried to find some argument for verbose output of these debuggers, or set a breakpoint (how to do that?) .. indeed you can also test on VM.

TampliteSK commented 3 months ago

I'm on my VM and while I do get 2 warnings trying to compile it, it's not the errors you got about the undefined functions. Have you tried removing both static and inline altogether? I still don't have an idea why it doesn't compile on your machine atm.

TampliteSK commented 3 months ago

I think the issue lies in the placement of fclose(pFile) in polybook.c. It appears to be the reason why gdb was spitting out that error. It should be fine now. The problem was I put it outside of the if-branch which causes issues when it tries to close the file pointer if it is NULL (i.e. the book file wasn't found).

tissatussa commented 3 months ago

i compiled your newest source code (after commit 454c02e) and without changing anything it went successfully :

$ make
cc src/attack.c src/bitboards.c src/board.c src/data.c src/endgame.c src/evaluate.c src/hashkeys.c src/init.c src/io.c src/main.c src/makemove.c src/misc.c src/movegen.c src/perft.c src/polybook.c src/polykeys.c src/pvtable.c src/search.c src/uci.c src/validate.c -o Dragonrose -Ofast -march=native -lm

$ ./Dragonrose 
uci
id name Dragonrose 0.28
id author Tamplite Siphron Kents
option name Hash type spin default 64 min 4 max 65536
option name Threads type spin default 1 min 1 max 1
option name Book type check default false
uciok

but then, playing a 5m+3s game in CuteChess GUI, the engine kept evaluating (upto depth 17) but no bestmove was given and it lost on time .. here's the full CuteChess log :

<Dragonrose v0.28(83): id name Dragonrose 0.28
<Dragonrose v0.28(83): id author Tamplite Siphron Kents
<Dragonrose v0.28(83): option name Hash type spin default 64 min 4 max 65536
<Dragonrose v0.28(83): option name Threads type spin default 1 min 1 max 1
<Dragonrose v0.28(83): option name Book type check default false
<Dragonrose v0.28(83): uciok
>Dragonrose v0.28(83): setoption name Book value false
>Dragonrose v0.28(83): setoption name Hash value 128
>Dragonrose v0.28(83): setoption name Threads value 1
>Dragonrose v0.28(83): isready
<Dragonrose v0.28(83): Set Book to false
<Dragonrose v0.28(83): Set Hash to 128 MB
<Dragonrose v0.28(83): readyok
<Kojiro v0.1(84): id name kojiro
<Kojiro v0.1(84): id author babak-ssh 
<Kojiro v0.1(84): option name Threads type spin default 1 min 1 max 512
<Kojiro v0.1(84): option name Hash type spin default 1 min 1 max 2048
<Kojiro v0.1(84): uciok
>Kojiro v0.1(84): setoption name Hash value 128
>Kojiro v0.1(84): setoption name Threads value 2
>Kojiro v0.1(84): isready
<Kojiro v0.1(84): readyok
>Dragonrose v0.28(83): ucinewgame
>Dragonrose v0.28(83): position startpos
>Kojiro v0.1(84): ucinewgame
>Kojiro v0.1(84): position startpos
>Dragonrose v0.28(83): isready
<Dragonrose v0.28(83): readyok
>Dragonrose v0.28(83): go wtime 303000 btime 303000 winc 3000 binc 3000
<Dragonrose v0.28(83): info score cp 42 depth 1 nodes 20 hashfull 0 time 0 pv g1f3
<Dragonrose v0.28(83): info score cp 0 depth 2 nodes 88 hashfull 0 time 0 pv g1f3 g8f6
<Dragonrose v0.28(83): info score cp 35 depth 3 nodes 694 hashfull 0 time 1 pv g1f3 g8f6 d2d4
<Dragonrose v0.28(83): info score cp 0 depth 4 nodes 2527 hashfull 0 time 3 pv g1f3 g8f6 d2d4 d7d5
<Dragonrose v0.28(83): info score cp 34 depth 5 nodes 5548 hashfull 0 time 8 pv g1f3 g8f6 d2d4 d7d5 c1f4
<Dragonrose v0.28(83): info score cp 12 depth 6 nodes 22761 hashfull 0 time 33 pv d2d3 d7d5 g1f3 g8f6 c1f4
<Dragonrose v0.28(83): info score cp 25 depth 7 nodes 61947 hashfull 2 time 81 pv g1f3 g8f6 d2d4 d7d5 c1f4 c8f5 f3e5
<Dragonrose v0.28(83): info score cp 22 depth 8 nodes 183348 hashfull 6 time 225 pv g1f3 g8f6 e2e3 c7c5 f1e2 d7d5 e1g1 b8c6
<Dragonrose v0.28(83): info score cp 21 depth 9 nodes 484613 hashfull 16 time 578 pv g1f3 d7d5 d2d4 b8d7 c1f4 d7f6 f3e5 c8f5
<Dragonrose v0.28(83): info score cp 29 depth 10 nodes 1561622 hashfull 47 time 1892 pv g1f3 d7d5 e2e3 c8f5 f1e2 b8c6 e1g1 c6b4 e2b5 c7c6
<Dragonrose v0.28(83): info score cp 26 depth 11 nodes 3229135 hashfull 96 time 3943 pv g1f3 c7c5 c2c4 g8f6 b1c3 d7d5 c4d5
<Dragonrose v0.28(83): info score cp 32 depth 12 nodes 7357367 hashfull 210 time 9027 pv g1f3 d7d5 e2e3 b8c6 f1e2 g8f6 d2d4 e7e6 e1g1 f8d6 b1c3 e8g8
<Dragonrose v0.28(83): info score cp 33 depth 13 nodes 14363174 hashfull 363 time 17671 pv g1f3 g8f6 e2e3 e7e5 f3e5 b8c6 d2d4 c6e5 d4e5 f6e4
<Dragonrose v0.28(83): info score cp 36 depth 14 nodes 24817453 hashfull 532 time 30931 pv g1f3 c7c5 b1c3 b8c6 e2e4 g8f6 f1e2 d7d5 e4d5 c6d4 f3d4 c5d4 e2b5
<Dragonrose v0.28(83): info score cp 41 depth 15 nodes 41973279 hashfull 722 time 52435 pv g1f3 d7d5 e2e3 b8c6 d2d4 c8f5 f1d3 f5d3 d1d3 g8f6 e1g1 c6d4 e3d4 e7e6 c1d2
<Dragonrose v0.28(83): info score cp 42 depth 16 nodes 69412764 hashfull 873 time 86626 pv g1f3 d7d5 e2e3 b8c6 d2d4 c8f5 f1b5 g8f6 e1g1 a7a6 b5c6 b7c6 f3e5 f5c2
<Dragonrose v0.28(83): info score cp 43 depth 17 nodes 127571618 hashfull 973 time 159998 pv g1f3 g8f6 e2e3 g7g6 d2d4 f8g7 f1d3 b8c6 b1d2 c6b4 d3e2 e8g8
>Dragonrose v0.28(83): stop
>Kojiro v0.1(84): isready
<Kojiro v0.1(84): readyok

btw. i compiled with cc (default), gcc-11 and gcc-13, and with & without the -Ofast : all went well, without any warnings or errors.

tissatussa commented 3 months ago

..Have you tried removing both static and inline altogether?

yesterday i did that, but nothing helped. today, as i wrote, i took your newest source and compiled it without changing anything (i didn't yet look in the code to see if you put 'inline' or 'static' or both ..)

tissatussa commented 3 months ago

btw. not giving a bestmove happens also when playing Black.

TampliteSK commented 2 months ago

Yeah seems to be another Linux issue. I think from now on I have to test on both environments before making a commit... I'll now look into this. Edit: ah it has to do with GetTimeMs()

tissatussa commented 2 months ago

it has to do with GetTimeMs()

good catch ! indeed i often had to fix such code part : the time functions on Linux differ a bit ..

TampliteSK commented 2 months ago

Could you test if the newest commit works? It's not a perfect solution because it lacks microseconds, assuming it doesn't immediately break. The pawn shield code is WIP so it'll probably lose elo

tissatussa commented 2 months ago

Could you test if the newest commit works? It's not a perfect solution because it lacks microseconds, assuming it doesn't immediately break.

yes, the newest commit (67d7b9f) works : i compiled without errors or warnings, like before, and the binary plays a valid game in CuteChess GUI.

i remember i also struggled with those microseconds function(s) : i think the milliseconds function(s) are default and they also work, but i'm not sure. Anyhow, you solved it !

TampliteSK commented 2 months ago

The original code uses sys/time.h gettimeofday() but it generates such a large number if you want to convert both seconds and microseconds into milliseconds, which seems to have caused overflow. The only concern I have with this fix is that the time might not be accurate for shorter time controls like bullet, or even ultrabullet for testing conditions.