Difference between revisions of "Debugging"

From Chessprogramming wiki
Jump to: navigation, search
Line 68: Line 68:
 
* [http://www.talkchess.com/forum/viewtopic.php?t=66366 Debugging UCI engine] by Cadel Watson, [[CCC]], January 19, 2018 » [[InBetween]], [[UCI]]
 
* [http://www.talkchess.com/forum/viewtopic.php?t=66366 Debugging UCI engine] by Cadel Watson, [[CCC]], January 19, 2018 » [[InBetween]], [[UCI]]
 
* [http://www.talkchess.com/forum3/viewtopic.php?f=7&t=67599 Debugging a transposition table] by [[Vincent Tang]], [[CCC]], May 29, 2018 » [[Transposition Table]], [[Lasker-Reichhelm Position]]
 
* [http://www.talkchess.com/forum3/viewtopic.php?f=7&t=67599 Debugging a transposition table] by [[Vincent Tang]], [[CCC]], May 29, 2018 » [[Transposition Table]], [[Lasker-Reichhelm Position]]
 +
==2020 ...==
 +
* [http://www.talkchess.com/forum3/viewtopic.php?f=7&t=74931 Engine Crash Detective Story] by [[Erik Madsen]], [[CCC]], August 29, 2020 » [[MadChess]]
  
 
=External Links=  
 
=External Links=  

Revision as of 18:10, 31 August 2020

Home * Programming * Debugging

Hin und her und rundherum
Kriecht es, fliegt es mit Gebrumm [1]

Debugging is a process of finding and reducing bugs in a computer program. A debugger, usually in software, allows to execute the program (debugee) under its control, to set breakpoints, let the user step to single lines of his source or machine code, to inspect variables, memory and processor registers. Processors often provide special instructions for the purpose of debugging.

x86 Breakpoints

8086, x86 and x86-64 have the int 3 one byte software interrupt instruction with opcode 0xCC, which might be explicitly used, or implicitly in assertions. This instruction is also used, when setting a breakpoint from a debugger, where current opcode is (temporarily) replaced by the int 3 opcode (0xCC), which when executed calls a special interrupt routine of the debugger or runtime system.

Breakpoint opcode may be inserted inside the code at compile time, for instance with x86 inline assembly or compiler intrinsic like DebugBreak [2] :

  __asm int 3

Compiler Support

Various compiler allow a special Debug build, which disables optimizations, default initialization of otherwise not initialized variables or memory, and/or enable runtime checking, like bounds checking of array access. Various integrated development environments (IDE) provide an integrated debugger.

Debugging the Search

A recursive search is quite hard to debug. Therefor chess programs may provide debug routines to use a sequence of certain moves or a zobrist key as a precondition to break the search if they occur. Here are Tord Romstad's suggestions in a reply to Patrice Duhamel [3]:

  • Extend the UCI/XBoard command set with a few commands of your own for use in debugging. In particular, it is useful to have a command for looking up the current position in the hash table and printing the information (score, score type, best move , etc). to the standard output. You can use this to browse the search tree after a search is finished. When you want to know why the program discarded some move, you can make the move and inspect the hash table entry for the corresponding position to find the score and refutation. I've found this to be a very valuable debugging technique, and even have a simple GUI app for browsing the tree (the GUI app communicates with the engine through pipes connected to the standard input and output).
  • The technique above can be further enhanced by including lots of additional information in the hash table when debugging the program. I sometimes store complete move lists with information about extension, reduction and pruning decisions for each move in every transposition table entry. Of course this makes each entry huge and greatly slows down the search, but it can be useful when chasing bugs or looking for ways to make the search more efficient.
  • Implement an MTD(f) search, even if you intend to use PVS. MTD(f) is great for debugging the hash table; all sorts of obscure bugs which are very tricky to find in PVS or other conventional searches suddenly become easy to spot.
  • Whenever you add some non-trivial new function to your program, try to write two versions: One which is very slow and stupid, but almost certainly correct, and one which is highly optimized. Verify on a huge number of positions that they give the same results. Remove the slow version only when you feel 100% sure that the fast version is correct.
  • Always make symmetry tests when you add a new term to your evaluation function .
  • Run through a simple tactical test like WAC at 5 seconds/move every time you change something important in your search. Don't try to optimize the results, but just make sure that the score doesn't suddenly drop dramatically.
  • Check the quality of your move ordering by measuring how often a beta cutoff occurs on the first move, and the frequencies with which the 1st, 2nd, 3rd, ... move turns out to be best at PV nodes.

See also

Publications

Forum Posts

2000 ...

2005 ...

Re: Testing and debugging chess engines by Tord Romstad, Winboard Forum, December 05, 2006

2010 ...

2015 ...

2020 ...

External Links

Brian W. Kernighan, Rob Pike (1999). The Practice of Programming. Addison-Wesley, ISBN: ISBN 0-201-61586-X

References

Up one Level