- ccompile(+File)
- Compile a file, inserting code coverage counters
- ccompile(+File, +OptionList)
- Compile a file, inserting code coverage counters
- point(?)
- No description available
- print_counters
- No description available
- reset_counters
- Reset all the coverage counters to zero
- result
- Pretty-print all files with code coverage results
- result(+File)
- Pretty-print a file, including any code coverage results
- result(+File, +OptionList)
- Pretty-print a file, including any code coverage results
This is a tool for obtaining code coverage information, i.e. information about which points in the code were executed how often during a particular run of the program.
The usage is as follows:
?- lib(coverage).
?- coverage:ccompile(my_program).
?- my_query(X,Y,Z).
?- coverage:result(my_program).
By default, code coverage counters are inserted before and after every subgoal in the code. For instance, in the clause
p :- q, r, s.four counters would be inserted: before the call to q, between q and r, between r and s, and after s:
p :- point(1), q, point(2), r, point(3), s, point(4).This is the most precise form provided. The counter values do not only show whether all code points were reached, they also show whether subgoals ever failed or aborted (in that case the counter before a subgoal will have a higher value than the counter after it). For example, the result of running the above code may look like:
p :- 43 q, 25 r, 25 s 0 .which would indicate that q was called 43 times, but succeeded only 25 times, r was called 25 times and succeeded always, and s was called 25 times and never succeeded. Coverage counts of zero are displayed in red because they indicate unreached code.
If one is only interested in knowing whether all code was covered, it is not necessary to have all these counters. point(1) and point(4) are enough to know whether q, r and s were successfully executed. The option blocks_only implements this: counters only get inserted at the beginning and at the end of conjunctions (comma-separated goal sequences), i.e. in the example:
p :- point(1), q, r, s, point(4).For big programs, the presence of counters at the end of clauses can cause problems because they prevent tail-recursion optimization and may lead to stack overflows. If that should be the case, exit-counters can be disabled by setting the exit_counters option to off, leading to the following incomplete instrumentation:
p :- point(1), q, point(2), r, point(3), s.
Note on the analysis of large, structured applications: Larger applications often consist of several modules which get compiled implicitly through use_module/1 directives. In this case, the module(s) that one wants to compile in coverage mode can be either compiled with ccompile/1 in advance (before loading the main application module), or afterwards (in which case ccompile/1 will replace the previously compiled normal code with coverage-code).
Limitation: The current implementation cannot deal with multiple (non-module) files that are ccompiled into the same module.