4.5. Tools to help with debugging and checking code quality#

4.5.1. b2code-module: Create a source code template for a module#

Tool to create a source code template for a module.

The command takes the name of the module as argument. It asks several questions, e.g. about the parameters or input/output data of the module, and then creates a header and source file. If inside a git repository they are added to it.

The code follows the conventions and can be compiled as is. The user only has to implement the actual functionality, usually inside the event() method.

usage: b2code-module modulename

Required Arguments

modulename

Name of the module

4.5.2. b2code-memoryusage: Show memory usage of a program#

Utility to measure the memory consumption of a process hierarchy on Linux.

This is optimized for basf2, taking into account page sharing for parallel processing mode and obtaining the process role from the output of basf2 if the log level of the framework is set to INFO.

This program has three modes: in “record” mode memory consumption is recorded for all children of the specified progam while it is executed. After execution is complete, the execution time (wall time) and maximum and average amount of memory used will be printed to stderr. Optionally, a memory consumption profile can be written to disk using the --profile argument. In “plot” mode, a previously recorded memory profile will be plotted as pdf file using the matplotlib plotting library and in mode “both” the memory profile will be recorded and plotted in one go.

Profiles can be generated for different types of memory consumption: virtual size which is (according to “man top”) the “total amount of virtual memory used by the task. It includes all code, data and shared libraries plus pages that have been swapped out and pages that have been mapped but not used.” Resident memory memory is the “non-swapped physical memory a task has used.” but does not take into account sharing between differnet processes. Proportional memory is like Resident memory but takes sharing of pages between processes into account. Swap is the amount of memory swapped out.

usage: b2code-memoryusage [optional arguments] [--] program [program arguments]

options

-m, --mode

Possible choices: record, plot, both

Indicates whether to record memory consumption, plot memory consumption or do both at once. If plot is selected a filename for the recorded data has to be specified using the –profile option (default: “both”)

-p, --profile

filename to write or read records from. Optional for mode=both and mode=record, required for mode=plot

-o, --output

Name of the output PDF file if plotting is enabled (default: “memoryusage.pdf”)

-i, --interval

sampling interval in seconds. Smaller interval increases precision at the cost of more cpu and memory utilization by this script (default: 1)

-t, --types

Memory types to record. Possible values are v=virtual size, r=resident size, p=proportional size, s=swap or any combination of these (default: “vrps”)

--system

If given, also record /proc/meminfo to check consistency. This only works well if no other programs are allocating memory while profile is recorded

--annotations

regular expession which to apply against output of program. If a match is found the contents of group 1 will be added to the plots at the time the output was processed

--no-legend

Omit legend from plot, useful for many cores as legend grows very large in that case

Examples

  • record the memory consumption of a steering file in four processor multiprocessing mode and write the results to console:

    $ b2code-memoryusage -m record -- basf2 -p4 steering.py
    
  • record the proportional and resident memory sizes with 100hz and write them to profile.npz:

    $ b2code-memoryusage -m record -i 0.01 -p profile.npz -t pr -- basf2 -p4 steering.py
    
  • plot the previously recorded profile.npz and save the plots as profile.pdf:

    $ b2code-memoryusage -m plot -p profile.npz -o profile.pdf
    
  • record and plot at once, all memory types except swap, take a value every 5 seconds, save the plots as profile.pdf and the data as profile.npz:

    $ b2code-memoryusage -i 5 -t vrp -p profile.npz -o profile.pdf -- basf2 -p4 steering.py
    
  • record the memory consumption of b2code-memoryusage itself when sampling with 100Hz while running sleep for 100 seconds:

    $ b2code-memoryusage -o self.pdf -- b2code-memoryusage -i 0.01 -m record -- sleep 100
    

4.5.3. b2code-findsymbol: Look for a given C++ symbol#

This script will try to find all libraries which contain a given C++ symbol. The intended use is to find out which library to add to the SConscript file as a dependency in case of an unresolved symbol error. Just run it with the symbol name as an argument:

b2code-findsymbol <symbolname>

The symbol name can be any valid grep pattern. It is advisable to quote the symbol name in single quotes to prevent the shell to interpret special characters. For example to look for Belle2::MCParticle::Class() one would use:

b2code-findsymbold 'Belle2::MCParticle::Class()'

It will print all the symbols found prefixed with the library name and a condensed list of all libraries containing the match at the end. When adding libraries to a SConscript please remove the lib prefix and .so extension.

4.5.4. b2code-doxygen-warnings: Show warnings when running doxygen#

This script will try to show all doxygen warnings about undocumented items similar to the development build. To run it on single files or directories just supply them as arguments:

b2code-doxygen-warnings [<directory>...] [<filename>...]

To run on the full release directory run it without any arguments:

b2code-doxygen-warnings

4.5.5. b2code-classversion-check: Perform sanity checks on ROOT class versions#

Tool to check that all ROOT dictionary information is correct and up to date as expected

This tool will look for all “linkdef.h” files and check if the classes mentioned in there are as expected, that is that the version is what we expect and that the checksum is unchanged. This is necessary to ensure we don’t accidentally modify the memory layout of a class without notifying ROOT about the change so that schema evolution can work correctly.

It looks through all linkdef files in the repository or in the directories given on the command line and will check if the version mentioned in the comment after each class link pragma matches with the generated values known to ROOT.

For each class there are two values:

  1. The class version, usually starting at 1 and mostly determined by the number given in the ClassDef macro. If the data layout of the class changes the version number needs to be increased so that ROOT can realize the class is different if for example reading an older version from a file.

  2. The class checksum, a short hexadecimal string representing a checksum over the class memory layout. It can be used to spot differences between different class versions: If the checksum changes the class version needs to be increased. However the checksum is not enough as one might want to increase the class version also for other reasons (memory layout the same but meaning of members changed).

Both values can be given in the comment after the class link pragma as comma separated key value list (for example // checksum=0x6eb1ad8, version=4). This tool can then spot changes and warn/fail if the the version or checksum of the actual class changes without an update to the values in the linkdef.

To simplify this procedure we have the tool b2code-classversion-update which can add and update this information automatically.

Added in version after: release-05-00-00

usage: b2code-classversion-check [-h] [--error-style {belle2,gcc}]
                                 [directory ...]

Required Arguments

directory

Name of a directory or linkdef file to check. If it’s a directory it will be searched recursively for linkdef files

options

--error-style

Possible choices: belle2, gcc

Allows to selectstyle similar to gcc instead of the normal basf2error to simplify parsing of errors on CI systems

4.5.6. b2code-classversion-update: Update linkdef information for sanity checks#

Tool to update the expected version and checksum for all ROOT classes in a linkdef file

This tool will look for all given “linkdef.h” files and update the comments for the classes to contain the class version and checksum from the compiled dictionary.

For a more detailed explanation please look at the documentation for b2code-classversion-check. But basically this tool looks for linkdef.h files in the given search folders and will update the class version and class checksum comments to reflect the actual values reported by ROOT when loading the class.

It will only update the values if no comments already exist or if version and checksum differ from the existing values and the class version increases by one. Otherwise it will report detailed errors on these cases so that the differences can be fixed manually.

Added in version after: release-05-00-00

usage: b2code-classversion-update [-h] directory [directory ...]

Required Arguments

directory

Name of a directory or linkdef file to check. If it’s a directory it will be searched recursively for linkdef files

4.5.7. b2code-cppcheck: Run cppcheck static analyzer#

This script will run cppcheck with the appropriate arguments to check for warnings from cppcheck as shown on the development build.

To run it on single files or directories just supply them as arguments:

b2code-cppcheck [<directory>...] [<filename>...]

To run on the full release directory run it without any arguments:

b2code-cppcheck

Additional options can be passed to cppcheck as well, for example -j to run cppcheck in parallel:

b2code-cppcheck -j50 framework

However in this case a directory to check has to be provided

4.5.8. b2code-option: Set up the environment for selected compiler options#

This tool sets up compiler options coding environment.

To run this tool:

b2code-option [-h] OPTION

Possible inputs for OPTION:

  • debug : use gcc compiler, include debug symbols, no optimization

  • opt : use gcc compiler, no debug symbols, turn on -O3 optimization

  • intel : use intel compiler, no debug symbols

  • clang : use clang compiler (LLVM), no debug symbols, turn on -O3 optimization

Optional Arguments

-h, --help

Show this help message and exit

4.5.9. b2code-parallel_processing-benchmark: Measure multi-core performance#

Measure multi-core execution time of given steering file with different number of processes. Output is a plot of relative performance (speedup) over number of cores (aka. -p argument to basf2). 0 cores equals true single-core mode.

usage: b2code-parallel_processing-benchmark [optional arguments] [--] STEERING_FILE [BASF2 OPTIONS]

options

-p

Try up to this many cores

-o

File name to save output PDF as.

-r

Number of repetitions for each measurement (minimum is used in plot)

--pf

Fraction of parallel code. Used to plot ideal line according to Amdahl’s law.

4.5.10. b2code-sphinx-build: Build the sphinx documentation#

This script will run sphinx with the appropriate arguments to build the user documentation and optionally only show the warnings.

Optional Arguments

--light

Create documentation only for the light release, that is only for the packages included in a light release build.

-t TARGET, --target TARGET

Documentation format to generate. If not given the default will be “html”. Available options are “html”, “latex”, “json”

-h, --help

Show this help message

-o, --output-dir

Where to put the documentation. If not given the default is the build directory in the software/release directory

All other options will be forwarded to sphinx-build

4.5.11. b2code-sphinx-warnings: Show all the warnings when building the documentation#

This script will create the sphinx documentation and check whether there are any warnings. All extra arguments are forwarded to b2code-sphinx-build.