The declarative debugger can operate in one of several modes when searching for a bug. Different search modes will result in different sequences of questions being asked by the declarative debugger. The user can specify which mode to use by giving the ‘--search-mode’ option to the ‘dd’ command (see Declarative debugging mdb commands) or with the ‘mode’ declarative debugger command (see Declarative debugging commands).
Using this mode the declarative debugger will ask about the children of the last question the user answered ‘no’ to. The child calls will be asked about in the order they were executed. This makes the search more predictable from the user’s point of view as the questions will more or less follow the program execution. The drawback of top-down search is that it may require a lot of questions to be answered before a bug is found, especially with deeply recursive programs.
This search mode is used by default when no other mode is specified.
With this search mode the declarative debugger attempts to halve the size of the search space with each question. In many cases this will result in the bug being found after O(log(N)) questions where N is the number of events between the event where the ‘dd’ command was given and the corresponding ‘CALL’ event. This makes the search feasible for long running programs where top-down search would require an unreasonably large number of questions to be answered. However, the questions may appear to come from unrelated parts of the program which can make them harder to answer.
In this search mode the declarative debugger assigns a suspicion level to each event based on which parts of the program were executed in failing test cases, but not in passing test cases. It then attempts to divide the search space into two areas of equal suspicion with each question. This tends to result in questions about parts of the program executed in a failing test case, but not in passing test cases.
The user may ask the declarative debugger to do a binary search along the path in the call tree between the current question and the question that the user last answered ‘no’ to. This is useful, for example, when a recursive predicate is producing incorrect output, but the base case is correct.